• laravel5.5学习2-路由系统


    一、初识路由

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

    Laravel 5.3 之后就把路由放到了 learnlaravel5/routes 文件夹中,一共有四个文件。

    我们先看一下web.php中仅存的几行代码:

    Route::get('/', function () {
        return view('welcome');
    });
    
    Auth::routes();
    
    Route::get('/home', 'HomeController@index')->name('home');

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

    二、命名空间

    我一直认为 Laravel 5 除了性能大幅提升之外相对于 4 最大的进步就在于新的命名空间规划:更清晰,更合理,更有利于新手。

    Laravel 4 失败的简洁

    Laravel 4 时代,大量的代码都运行在根命名空间下,路由、Controller、Model 等等。看起来这么做可以少写几行枯燥的 use xxxx;,实则是对于命名空间的误使用,而且对于新手学习命名空间是有毒的。

    绝对类名

    Laravel 5 全面引入了 psr-4 命名空间标准:命名空间和实际文件所在的文件夹层级一致,文件夹首字母大写,并自动成为此文件的约定命名空间。举个小栗子:learnlaravel5/app/Http/Controllers/HomeController.php 的绝对类名为:AppHttpControllersHomeControllerlearnlaravel5/app/User.php 的绝对类名为:AppUser。(实际上 psr-4 是自动加载标准,用在这里故称其为命名空间标准。)

    “绝对类名”是我自创的:在启用了命名空间的系统中,子命名空间下的类有一个全局都可以直接访问的名称,这个名称就是该类的命名空间全称。虽然命名空间在“实用主义”的 PHP 语言里看起来十分古怪,不过他也还是 PHP 嘛,依然遵循 PHP 的运行原理和哲学。同理,Laravel 无论多么强大,他都是 PHP 代码写成的,所以当你苦于 Laravel 没有提供某个你需要的功能时,不要惊慌不要着急,just write your PHP code。

    三、基础路由解析

    1、闭包路由

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

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

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

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

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

    'timezone' => 'Asia/Shanghai',

    3、控制器@方法 路由

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

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

    这行路由代码的意思想必大家都能猜到一二了:当以 GET 方法访问 http://fuck.io:1024/home 的时候,调用 HomeController 控制器中的 index 方法(函数)。同理,你可以使用 Route::post('/home', 'HomeController@indexPost'); 响应 POST 方法的请求。最后的->name()不是必须的,感兴趣可以自己了解。

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

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

    learnlaravel5/app/Providers/RouteServiceProvider.php

    全局搜索 routes.php,我们找到了这个文件。此文件最后的 mapWebRoutes 方法,给所有的路由统一加进了一个路由组,定义了一个命名空间和一个中间件

    protected function mapWebRoutes()
    {
        Route::middleware('web')
             ->namespace($this->namespace)
             ->group(base_path('routes/web.php'));
    }

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

    protected $namespace = 'AppHttpControllers';

    之后命名空间、类、方法是如何传递的呢?

    learnlaravel5/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php

    经过简单的追踪,我们找到了这个文件。让我们在 dispatch 方法中增加一行 var_dump($controller);,刷新http://127.0.0.1:8000:1024/home就可以看到页面上如下的输出:

    开头的AppHttpControllersHomeController就是我们要调用的控制器类的“绝对类名”,注意这里是不带根命名空间符号的。

    四、增加路由组

    路由组可以给组内路由一次性增加 命名空间、uri 前缀、域名限定、中间件 等属性,并且可以多级嵌套,异常强大。

    如:我们要使用路由组来将后台页面置于“需要登录才能访问”的中间件下,以保证安全。在Routes/web.php 里增加下面三行:

    Route::group(['middleware' => 'auth', 'namespace' => 'Admin', 'prefix' => 'admin'], function() {
        Route::get('/', 'HomeController@index');
    });

    命名空间

    另一个常见用例是使用 namespace 方法将相同的 PHP 命名空间分配给路由组的中所有的控制器:

    Route::namespace('Admin')->group(function () {
        // 在 "AppHttpControllersAdmin" 命名空间下的控制器
    });

    请记住,默认情况下,RouteServiceProvider 会在命名空间组中引入你的路由文件,让你不用指定完整的 AppHttpControllers 命名空间前缀就能注册控制器路由。因此,你只需要指定命名空间 AppHttpControllers 之后的部分。

    五、CSRF 保护

    指向 web 路由文件中定义的 POSTPUT 或 DELETE 路由的任何 HTML 表单都应该包含一个 CSRF 令牌字段,否则,这个请求将会被拒绝。可以在 CSRF 文档 中阅读有关 CSRF 保护的更多信息:

    <form method="POST" action="/profile">
        {{ csrf_field() }}
        ...
    </form>

    六、表单方法伪造

    HTML 表单不支持 PUTPATCH 或 DELETE 行为。所以当你要从 HTML 表单中调用定义了 PUTPATCH 或 DELETE 路由时,你将需要在表单中增加隐藏的 _method 输入标签。使用 _method 字段的值作为 HTTP 的请求方法:

    <form action="/foo/bar" method="POST">
        <input type="hidden" name="_method" value="PUT">
        <input type="hidden" name="_token" value="{{ csrf_token() }}">
    </form>

    你也可以使用辅助函数 method_field 来生成隐藏的 _method 输入标签:

    {{ method_field('PUT') }}
     
  • 相关阅读:
    VuGen错误处理函数
    LR的日志
    创建性能测试脚本时如何选择HTML模式和URL模式
    Java变量
    查找&排序
    selenium执行JS
    Python中 is 和 == 的区别
    Python中 and or的计算规则
    selenium使用location定位元素坐标偏差
    错误:Could not find an available JavaScript runtime
  • 原文地址:https://www.cnblogs.com/ivy-zheng/p/11048653.html
Copyright © 2020-2023  润新知