Laravel—路由

路由

路由:将信息从源地址传递到目的地的角色,相当于后台函数处理 

路由定义:

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

路由文件在Laravel/routes目录中,大部分应用的构建都在web.php中定义,可以通过url访问定义的路由:DomainName/foo,其中foo为自己定义的标识符

可用的路由方法

有多种与http响应的方式

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

多个可响应HTTP请求的路由

使用match方法,也可以使用any方法注册一个实现所有HTTP请求的路由

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

CSRF保护

web路由文件中定义的post,put,delete路由,在HTML表单中要包含一个CSRF令牌字段,否则,这个请求会被拒绝

<form method="POST" action="/profile">
    @csrf
    ...
</form>

重定向路由

定义一个路由指向另一个URL路由,使用Route::redirect,实现快速实现重定向

Route::redirect(‘/here’,’/there’,301);//301表示永久重定向,302表示临时重定向

视图路由

用于返回一个试图,使用Route::view,view有三个参数,前两个为必填,分别为URI视图名称,后一个可选,可以传入一个数组给视图

Route::view('/welcome','welcome');
Route::view('/welcome','welcome',['name'=>'XiaoMing']);

路由参数

  • 必填参数
    参数名称不能包含-字符,路由参数被注入路由回调/控制器取决于它们的顺序,与名称无关
//一个参数
Route::get('user/{id}',function($id){
    return 'User '.$id;
});

//多个参数
Route::get('posts/{post}/comments/{comment}',function($postId,$commentId){
    return $postId . '-' . $commentId;
});
  • 可选参数
    可以通过在参数名后加一个?标记这是可选参数,这种情况下要给相应的变量指定默认值
Route::get('user/{name?}',function($name = null){
    return $name;
});

Route::get('user/{name?}',function($name = 'John'){
    return $name;
});

正则约束

可以通过where方法来约束路由的参数格式,where接受参数名和一个正则表达式来定义该参数如何被约束

Route::get('user/{name}',function($name){
    //$name必须是字母并且不为空
})->where('name','[A-Za-z]+');

Route::get('user/{id}',function($id){
    //$id必须是数字
})->where('id','[0-9]+');

Route::get('user/{id}/{name}',function($id,$name){
    //同时指定id和name的数据格式
})->where(['id' =>'[0-9]+','name' => '[a-z]+']);

全局约束

使用pattern方法,可以全局的参数被给定的正则表达式约束,需要在app/provides/RouteServiceProvider中的boot方法中定义这种约束模式

   /**
     * 定义路由模型绑定,模式过滤器等
     * 全局的id参数都被限制
     *
     * @return void
     */
    public function boot()
    {
        //
        Route::pattern('id','[0-9]+');
        parent::boot();
    }

命名路由

在路由定义之后使用name定义路由的名称

  • route()返回该路由的URL地址,还可以传递第二个参数给route
//会生成:my url: http://localhost/user/profile
Route::get('user/profile',function(){
    //通过路由名称生成URL
    return 'my url: '. route('profile');
})->name('profile');

//生成跟网址一样的url:http://localhost/user/123/profile
Route::get('/user/{id}/profile',function(){
    $url = 'my uel: '.route('profile',['id'=>$id]);
    return $url;
})->name('profile');

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

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

这样就可以通过以下方法进行重定向:

  • redirect()函数用于重定向
Route::get('redirect',function(){
    //通过路由名称重定向
    return redirect()->route('profile');
});

路由分组

可以让多个路由共享相同的路由属性,共享属性以数组的形式作为第一个参数被传递给Route::group方法

Route::group(function(){
    //各个使用的路由
});

子路由

即路由的嵌套,使用domain方法来指定

Route::domain('{account}.blog.dev')->group(function(){
    Route::get('/user/{id}',function ($account,$id){
        Freturn 'This is ' . $account . ' page of User ' . $id;
    });
});

如果输入:http://account.blog.test/user/1 ,则显示出:This is account page of User 1

路由前缀

profix方法可以为分组中的每个路由添加一个URI前缀

Route::prefix('admin')->group(function() {
    Route::get('user',function(){
        //代码
    });
});

这样以后访问路由的网址便是http://localhost/admin/user

路由名称前缀

name方法可以为每个路由的名字就上前缀

Route::name('admin.')->group(function(){
    Route::get('user',function(){
        //新的路由名为"admin.user"
    })->name('user');
});

频率限制

Laravel自带了一个中间件用于限制应用路由的访问频率,分配throttle中间件到某个路由或路由分组,throttle中间件接受两个参数用于判断给定时间(单位:分钟)内的最大请求次数,超出访问次数会报429状态码并提示“Too many requests”

//指定登陆用户每分钟内只能访问下面的分组路由60次
Route::middleware('auth:api','throttle:60,1')->group(function(){
    Route::get('/user',function({
        //
    }));
});

表单伪造方法

HTML表单不支持PUT,PATCH,DELETE行为,当要从HTML表单中调用定义了的PUT、PATCH、DELETE路由时,需要在表单中增加隐藏的_method输入标签,value值为相应的请求方法

<!-- 第一种方法 -->
<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{crsf_token() }}">
</form>

<!-- 第二种方法 -->
<form action="/foo/bar" method="POST">
     @method('PUT')
     @csrf    
</form>