学习Laravel-5(二)路由

∥☆過路亽.° 提交于 2020-02-14 00:08:40

##初识路由

路由系统是所有 PHP 框架的核心,路由承载的是 URL 到代码片段的映射,不同的框架所附带的路由系统是这个框架本质最真实的写照,一丝不挂,一览无余。Laravel 路由中文文档:http://laravel-china.org/docs/5.1/routing

Laravel 5 之后就把路由放到了 learnlaravel5/app/Http/routes.php 这个位置,我们先看一下目前路由中仅存的几行代码:

    Route::get('/', function () {
        return view('welcome');
    });
    
    Route::auth();
    
    Route::get('/home', 'HomeController@index');

中间的一行代码 Route::auth(); 就是 Auth 系统自动注入的路由配置,我们不用深究,我们的注意力主要集中头三行和最后一行代码上。

##绝对类名

Laravel 5 全面引入了 psr-4 命名空间标准:命名空间和实际文件所在的文件夹层级一致,文件夹首字母大写即为此文件的约定命名空间。举个例子:learnlaravel5/app/Http/Controllers/HomeController.php 的绝对类名为:\App\Http\Controllers\HomeController,learnlaravel5/app/User.php 的绝对类名为:\App\User。

在启用了命名空间的系统中,子命名空间下的类有一个全局都可以直接访问的名称,这个名称就是该类的命名空间全称。虽然命名空间在PHP 语言里依然遵循 PHP 的运行原理和哲学。同理,Laravel 无论多么强大,他都是 PHP 代码写成的,所以当你苦于 Laravel 没有提供某个你需要的功能时,不要惊慌不要着急,just write the code in the PHP way。

    psr-4 的官方英文文档在这里:http://www.php-fig.org/psr/psr-4/

##基础路由解析
####闭包路由

路由文件中前三行即为闭包路由:

    Route::get('/', function () {
        return view('welcome');
    });

闭包路由使用闭包作为此条请求的响应代码,方便灵活,很多简单操作直接在闭包里解决即可。例如“输出服务器当前时间”:

Route::get('now', function () {
    return date("Y-m-d H:i:s");
});

如果你想得到北京时间,请在 learnlaravel5/config/app.php 第 55 行左右把 timezone 设置为上海:

    'timezone' => 'Asia/Shanghai',

这时候访问 http://www.learnlaravel5.hk 可以得到如下结果:




####控制器@方法 路由

闭包路由虽然灵活强大,不过大多数场景下我们还是需要回归到 MVC 架构的:

    Route::get('/home', 'HomeController@index');

这行路由代码的意思想必大家都能猜到一二了:当以 GET 方法访问 http://www.learnlaravel5.hk/home 的时候,调用 HomeController 控制器中的 index 方法(函数)。同理,你可以使用 Route::post('/home', 'HomeController@indexPost'); 响应 POST 方法的请求。

####控制器@方法 调用原理浅析

Laravel 的路由跟所有 PHP 框架的路由一样,都是用的最简单直接的 PHP 方式来调用控制器中的方法的:使用字符串初始化类得到对象,调用对象的指定方法,返回结果。下面我简单罗列几步对 Laravel 路由调用过程的探测,感兴趣的话可以自己研究。

我们找到了文件learnlaravel5/app/Providers/RouteServiceProvider.php。此文件最后的 mapWebRoutes 方法,给所有的路由统一加进了一个路由组,定义了一个命名空间和一个中间件:

    protected function mapWebRoutes(Router $router)
    {
        $router->group([
            'namespace' => $this->namespace, 'middleware' => 'web',
        ], function ($router) {
            require app_path('Http/routes.php');
        });
    }

顺着这个函数往上看,你会发现命名空间定义的地方:

    protected $namespace = 'App\Http\Controllers';

之后命名空间、类、方法是如何传递的呢?
    learnlaravel5/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php

经过简单的追踪,我们找到了这个文件。让我们在 dispatch 方法中增加一行 var_dump($controller);例如login操作可以看到页面上如下的输出:



##最后一步

Laravel 使用了完整的面向对象程序架构,对控制器的调用进行了超多层封装,所以最简单地探测方式其实是手动抛出错误,这样就可以看到完整的调用栈:

在 HomeController 的 index 方法里的 return 之前增加一行
     throw new \Exception("我故意的", 1);
刷新页面,你将看到以下画面:


我们可以看到,是 learnlaravel5/vendor/laravel/framework/src/Illuminate/Routing/Controller.php 第 80 行最终驱动起了 HomeController:

    public function callAction($method, $parameters)
    {
        return call_user_func_array([$this, $method], $parameters);

    }

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!