zoukankan      html  css  js  c++  java
  • HTTP层 —— 路由

     

    1、基本路由

    最基本的 Laravel 路由只接收一个 URI 和一个闭包,并以此提供一个非常简单且优雅的定义路由方法:

    Route::get('foo', function () {
        return 'Hello World';
    });
    

    默认路由文件

    所有Laravel路由都定义位于routes目录下的路由文件中,这些文件通过框架自动加载。routes/web.php文件定义了web界面的路由,这些路由被分配给web中间件组,从而可以提供session和csrf防护等功能。routes/api.php中的路由是无状态的,被分配到api中间件组。

    对大多数应用而言,都是从 routes/web.php 文件开始定义路由。

    有效的路由方法

    我们可以注册路由来响应任何 HTTP 请求:

    Route::get($uri, $callback);
    Route::post($uri, $callback);
    Route::put($uri, $callback);
    Route::patch($uri, $callback);
    Route::delete($uri, $callback);
    Route::options($uri, $callback);
    

    有时候还需要注册路由响应多个 HTTP 请求——这可以通过 match 方法来实现。或者,可以使用 any 方法注册一个路由来响应所有 HTTP 请求:

    Route::match(['get', 'post'], '/', function () {
        //
    });
    Route::any('foo', function () {
        //
    });
    

    CSRF防护

    web路由文件中所有请求方式为PUTPOSTDELETE的HTML表单都会包含一个CSRF令牌字段,否则,请求会被拒绝。关于CSRF的更多细节,可以参考其文档

    <form method="POST" action="/profile">
        {{ csrf_field() }}
        ...
    </form>
    
    2、路由参数
    必选参数

    有时我们需要在路由中捕获 URI 片段。比如,要从 URL 中捕获用户 ID,需要通过如下方式定义路由参数:

    Route::get('user/{id}', function ($id) {
        return 'User '.$id;
    });
    

    可以按需要在路由中定义多个路由参数:

    Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
        //
    });
    

    路由参数总是通过花括号进行包裹,这些参数在路由被执行时会被传递到路由的闭包。

    注意:路由参数不能包含 - 字符,需要的话可以使用 _ 替代。

    可选参数

    有时候可能需要指定可选的路由参数,这可以通过在参数名后加一个 ? 标记来实现,这种情况下需要给相应的变量指定默认值:

    Route::get('user/{name?}', function ($name = null) {
        return $name;
    });
    Route::get('user/{name?}', function ($name = 'John') {
        return $name;
    });
    
    3、命名路由

    命名路由为生成 URL 或重定向提供了便利。实现也很简单,在路由定义之后使用 name 方法链的方式来实现:

    Route::get('user/profile', function () {
        //
    })->name('profile');
    

    还可以为控制器动作指定路由名称:

    Route::get('user/profile', 'UserController@showProfile')->name('profile');
    

    为命名路由生成URL

    为给定路由分配名称之后,就可以通过辅助函数 route 为该命名路由生成 URL:

    $url = route('profile');
    $redirect = redirect()->route('profile');
    

    如果命名路由定义了参数,可以将该参数作为第二个参数传递给 route 函数。给定的路由参数将会自动插入到 URL 中:

    Route::get('user/{id}/profile', ['as' => 'profile', function ($id) {
        //
    }]);
    $url = route('profile', ['id' => 1]);
    
    4、路由群组

    路由群组允许我们在多个路由中共享路由属性,比如中间件和命名空间等,这样的话我们就不必为每一个路由单独定义属性。共享属性以数组的形式作为第一个参数被传递给 Route::group 方法。

    中间件

    要给路由群组中定义的所有路由分配中间件,可以在群组属性数组中使用 middleware。中间件将会按照数组中定义的顺序依次执行:

    Route::group(['middleware' => 'auth'], function () {
        Route::get('/', function () {
            // 使用 Auth 中间件
        });
    
        Route::get('user/profile', function () {
            // 使用 Auth 中间件
        });
    });
    
    命名空间

    另一个通用的例子是路由群组分配同一个 PHP 命名空间给其下的多个控制器,可以在分组属性数组中使用 namespace来指定群组中所有控制器的公共命名空间:

    Route::group(['namespace' => 'Admin'], function(){
        // 控制器在 "AppHttpControllersAdmin" 命名空间下
    
        Route::group(['namespace' => 'User'], function(){
            // 控制器在 "AppHttpControllersAdminUser" 命名空间下
        });
    });
    

    默认情况下,RouteServiceProvider 引入你的路由文件并指定其下所有控制器类所在的默认命名空间AppHttpControllers,因此,我们在定义的时候只需要指定命名空间 AppHttpControllers 之后的部分即可。

    子域名路由

    路由群组还可以被用于子域名路由通配符,子域名可以像 URI 一样被分配给路由参数,从而允许捕获子域名的部分用于路由或者控制器,子域名可以通过群组属性数组中的 domain 来指定:

    Route::group(['domain' => '{account}.myapp.com'], function () {
        Route::get('user/{id}', function ($account, $id) {
            //
        });
    });
    
    路由前缀

    群组属性 prefix 可以用来为群组中每个路由添加一个给定 URI 前缀,例如,你可以为所有路由 URI 添加 admin 前缀 :

    Route::group(['prefix' => 'admin'], function () {
        Route::get('users', function () {
            // 匹配 "/admin/users" URL
        });
    });
    
    5、路由模型绑定

    注入模型ID到路由或控制器动作时,通常需要查询数据库才能获取相应的模型数据。Laravel 路由模型绑定让注入模型实例到路由变得简单,例如,你可以将匹配给定 ID 的整个 User 类实例注入到路由中,而不是直接注入用户 ID。

    隐式绑定

    Laravel 会自动解析定义在路由或控制器动作(变量名匹配路由片段)中的 Eloquent 模型类型声明,例如:

    Route::get('api/users/{user}', function (AppUser $user) {
        return $user->email;
    });
    

    在这个例子中,由于类型声明了 Eloquent 模型 AppUser,对应的变量名 $user 会匹配路由片段中的{user},这样,Laravel 会自动注入与请求 URI 中传入的 ID 对应的用户模型实例。

    如果数据库中找不到对应的模型实例,会自动生成 HTTP 404 响应。

    自定义键名

    如果你想要隐式模型绑定使用数据表的其它字段,可以重写 Eloquent 模型类的 getRouteKeyName 方法:

    /**
     * Get the route key for the model.
     *
     * @return string
     */
    public function getRouteKeyName()
    {
        return 'slug';
    }
    
    显式绑定

    要注册显式绑定,需要使用路由的 model 方法来为给定参数指定绑定类。应该在 RouteServiceProvider::boot 方法中定义模型绑定:

    绑定参数到模型

    public function boot()
    {
        parent::boot();
        $router->model('user', 'AppUser');
    }
    

    接下来,定义一个包含 {user} 参数的路由:

    $router->get('profile/{user}', function(AppUser $user) {
         //
    });
    

    由于我们已经绑定 {user} 参数到 AppUser 模型,User 实例会被注入到该路由。因此,如果请求 URL 是profile/1,就会注入一个用户 ID 为 1 的 User 实例。

    如果匹配的模型实例在数据库不存在,会自动生成并返回 HTTP 404 响应。

    自定义解析逻辑

    如果你想要使用自定义的解析逻辑,需要使用 Route::bind 方法,传递到 bind 方法的闭包会获取到 URI 请求参数中的值,并且返回你想要在该路由中注入的类实例:

    $router->bind('user', function($value) {
        return AppUser::where('name', $value)->first();
    });
    
    6、表单方法伪造

    HTML 表单不支持 PUTPATCH 或者 DELETE 请求方法,因此,当定义 PUTPATCHDELETE 路由时,需要添加一个隐藏的 _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_field('PUT') }}
    
    7、访问当前路由

    你可以使用 Route 门面上的 currentcurrentRouteNamecurrentRouteAction 方法来访问处理当前输入请求的路由信息:

    $route = Route::current();
    $name = Route::currentRouteName();
    $action = Route::currentRouteAction();
    

    参考API文档了解路由门面底层类以及Route实例的更多可用方法。

  • 相关阅读:
    从Oracle提供两种cube产品说开
    Sql Server DWBI的几个学习资料
    Unload Oracle data into text file
    初学Java的几个tips
    我常用的Oracle知识点汇总
    benefits by using svn
    如何在windows上使用putty来显示远端linux的桌面
    building commercial website using Microsoft tech stack
    Understand Thread and Lock
    Update google calendar by sunbird
  • 原文地址:https://www.cnblogs.com/zhengyanbin2016/p/6005035.html
Copyright © 2011-2022 走看看