1、基本路由
最基本的 Laravel
路由只接收一個(gè) URI
和一個(gè)閉包
罕拂,并以此提供一個(gè)非常簡(jiǎn)單且優(yōu)雅的定義路由方法:
Route::get('foo', function () {
return 'Hello World';
});
默認(rèn)路由文件
有 Laravel 路由都定義在位于 routes
目錄下的路由文件中埋合,這些文件通過(guò)框架自動(dòng)加載备徐。
routes/web.php
文件定義了web界面的路由,這些路由被分配了web
中間件組甚颂,從而可以提供session和csrf防護(hù)等功能蜜猾。
routes/api.php
中的路由是無(wú)狀態(tài)的,被分配了 api
中間件組西设。
對(duì)大多數(shù)應(yīng)用而言瓣铣,都是從 routes/web.php
文件開始定義路由。
我們可以注冊(cè)路由來(lái)響應(yīng)任何 HTTP 請(qǐng)求:
//get 請(qǐng)求
Route::get($uri, $callback);
//post 請(qǐng)求
Route::post($uri, $callback);
//put 請(qǐng)求
Route::put($uri, $callback);
//patch 請(qǐng)求
Route::patch($uri, $callback);
//delete 請(qǐng)求
Route::delete($uri, $callback);
//options 請(qǐng)求
Route::options($uri, $callback);
有時(shí)候還需要注冊(cè)路由響應(yīng)多個(gè) HTTP
請(qǐng)求——這可以通過(guò) match
方法來(lái)實(shí)現(xiàn)贷揽√男Γ或者,可以使用 any
方法注冊(cè)一個(gè)路由來(lái)響應(yīng)所有 HTTP 請(qǐng)求:
Route::match(['get', 'post'], '/', function () {
//
});
Route::any('foo', function () {
//
});
CSRF防護(hù)
在 web
路由文件中所有請(qǐng)求方式為PUT
禽绪、POST
或DELETE
的HTML表單都會(huì)包含一個(gè)CSRF令牌
字段蓖救,否則,請(qǐng)求會(huì)被拒絕印屁。關(guān)于CSRF的更多細(xì)節(jié)循捺,可以參考CSRF文檔:
<form method="POST" action="/profile">
{{ csrf_field() }}
...
</form>
2、路由參數(shù)
必選參數(shù)
有時(shí)我們需要在路由中捕獲 URI 片段雄人。比如从橘,要從 URL
中捕獲用戶ID
念赶,需要通過(guò)如下方式定義路由參數(shù):
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});
可以按需要在路由中定義多個(gè)路由參數(shù):
Route::get('/hello/{name}/by/{user}',function($name,$user){
return "Hello {$name} by {$user}!";
});
路由參數(shù)總是通過(guò){}
進(jìn)行包裹,這些參數(shù)在路由被執(zhí)行時(shí)會(huì)被傳遞到路由的閉包恰力。路由參數(shù)不能包含 -
字符叉谜,需要的話可以使用 _
替代。
注意以上參數(shù)是必選的踩萎,如果沒(méi)有輸入?yún)?shù)會(huì)拋出 MethodNotAllowedHttpException
或 NotFoundHttpException
異常停局。
此外閉包函數(shù)中的參數(shù)與路由參數(shù)一一對(duì)應(yīng)。
可選參數(shù)
有時(shí)候可能需要指定可選的路由參數(shù)香府,這可以通過(guò)在參數(shù)名后加一個(gè) ?
標(biāo)記來(lái)實(shí)現(xiàn)董栽,這種情況下需要給相應(yīng)的變量指定默認(rèn)值:
Route::get('user/{name?}', function ($name = null) {
return $name;
});
Route::get('user/{name?}', function ($name = 'John') {
return $name;
});
正則約束
可以使用路由實(shí)例上的 where
方法來(lái)約束路由參數(shù)的格式。where
方法接收參數(shù)名
為鍵和一個(gè)正則表達(dá)式
為值的數(shù)組來(lái)定義該參數(shù)如何被約束:
Route::get('user/{name}', function ($name) {
//
})->where('name', '[A-Za-z]+');
Route::get('user/{id}', function ($id) {
//
})->where('id', '[0-9]+');
Route::get('user/{id}/{name}', function ($id, $name) {
//
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
全局約束
如果想要路由參數(shù)在全局范圍內(nèi)被給定正則表達(dá)式約束企孩,可以使用 pattern
方法锭碳。在RouteServiceProvider
類的 boot
方法中定義約束模式:
/**
* 定義路由模型綁定,模式過(guò)濾器等
*
* @param \Illuminate\Routing\Router $router
* @return void
* @translator
*/
public function boot(){
Route::pattern('id', '[0-9]+');
parent::boot();
}
一旦模式被定義,將會(huì)自動(dòng)應(yīng)用到所有包含該參數(shù)名的路由中:
Route::get('user/{id}', function ($id) {
// 只有當(dāng) {id} 是數(shù)字時(shí)才會(huì)被調(diào)用
});
3勿璃、命名路由
命名路由為生成 URL
或重定向
提供了便利工禾。實(shí)現(xiàn)也很簡(jiǎn)單,在路由定義之后使用 name
方法鏈的方式來(lái)實(shí)現(xiàn):
Route::get('user/profile', function () {
//
})->name('profile');
還可以為控制器動(dòng)作指定路由名稱:
Route::get('user/profile', 'UserController@showProfile')->name('profile');
為命名路由生成URL
或重定向
給定路由分配名稱之后蝗柔,就可以通過(guò)輔助函數(shù) route 為該命名路由生成 URL:
$url = route('profile');
return redirect()->route('profile');
如果命名路由定義了參數(shù),可以將該參數(shù)作為第二個(gè)參數(shù)傳遞給 route
函數(shù)民泵。給定的路由參數(shù)將會(huì)自動(dòng)插入到 URL
中:
Route::get('user/{id}/profile', function ($id) {
//
})->name('profile');
$url = route('profile', ['id' => 1]);
4癣丧、路由群組
路由分組就是將一組擁有相同屬性(中間件
、命名空間
栈妆、子域名
胁编、路由前綴
等)的路由使用 Route Facade
的 group
方法聚合起來(lái)。
共享屬性以數(shù)組的形式作為第一個(gè)參數(shù)被傳遞給 Route::group
方法鳞尔。
中間件
要給路由群組中定義的所有路由分配中間件嬉橙,可以在群組屬性數(shù)組中使用 middleware
。中間件將會(huì)按照數(shù)組中定義的順序依次執(zhí)行:
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// 使用 Auth 中間件
});
Route::get('user/profile', function () {
// 使用 Auth 中間件
});
});
命名空間
命名空間可以通過(guò)namespace
關(guān)鍵字來(lái)設(shè)置寥假。
默認(rèn)情況下市框, RouteServiceProvider
引入你的路由文件并指定其下所有控制器類所在的默認(rèn)命名空間App\Http\Controllers
,因此糕韧,我們?cè)诙x的時(shí)候只需要指定命名空間 App\Http\Controllers
之后的部分即可 :
Route::group(['namespace' => 'Admin'], function(){
// 控制器在 "App\Http\Controllers\Admin" 命名空間下
});
子域名路由
子域名可以通過(guò)domain
關(guān)鍵字來(lái)設(shè)置 :
Route::group(['domain' => '{account}.myapp.com'], function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
這樣我們?cè)跒g覽器中訪問(wèn)http://xiao.myapp.com/user/5枫振。
路由前綴
路由前綴可以通過(guò) prefix 關(guān)鍵字來(lái)設(shè)置 :
Route::group(['prefix' => 'admin'], function () {
Route::get('users', function () {
// 匹配 "/admin/users" URL
});
});
5、路由模型綁定
注入模型ID到路由或控制器動(dòng)作時(shí)萤彩,通常需要查詢數(shù)據(jù)庫(kù)才能獲取相應(yīng)的模型數(shù)據(jù)粪滤。Laravel 路由模型綁定讓注入模型實(shí)例到路由變得簡(jiǎn)單,例如雀扶,你可以將匹配給定 ID 的整個(gè) User 類實(shí)例注入到路由中杖小,而不是直接注入用戶ID。
隱式綁定
Laravel 會(huì)自動(dòng)解析定義在路由或控制器動(dòng)作(變量名匹配路由片段)中的 Eloquent
模型類型聲明,例如:
Route::get('api/users/{user}', function (App\User $user) {
return $user->email;
});
在這個(gè)例子中予权,由于類型聲明了 Eloquent
模型 App\User
昂勉,對(duì)應(yīng)的變量名 $user
會(huì)匹配路由片段中的 {user}
,這樣伟件,Laravel 會(huì)自動(dòng)注入與請(qǐng)求 URI 中傳入的 ID 對(duì)應(yīng)的用戶模型實(shí)例硼啤。
如果數(shù)據(jù)庫(kù)中找不到對(duì)應(yīng)的模型實(shí)例,會(huì)自動(dòng)生成 HTTP 404 響應(yīng)斧账。
自定義鍵名
如果你想要在隱式模型綁定中使用數(shù)據(jù)表的其它字段谴返,可以重寫 Eloquent 模型類的 getRouteKeyName 方法:
/**
* 獲取模型的路由密鑰.
*
* @return string
*/
public function getRouteKeyName()
{
return 'slug';
}
顯式綁定
要注冊(cè)顯式綁定,需要使用路由的 model
方法來(lái)為給定參數(shù)指定綁定類咧织。應(yīng)該在 RouteServiceProvider
類的 boot
方法中定義模型綁定:
public function boot()
{
parent::boot();
Route::model('user', App\User::class);
}
接下來(lái)嗓袱,定義一個(gè)包含 {user}
參數(shù)的路由:
$router->get('profile/{user}', function(App\User $user) {
//
});
由于我們已經(jīng)綁定 {user}
參數(shù)到 App\User
模型,User
實(shí)例會(huì)被注入到該路由习绢。因此渠抹,如果請(qǐng)求 URL 是 profile/1
,就會(huì)注入一個(gè)用戶 ID 為 1
的 User
實(shí)例闪萄。
如果匹配的模型實(shí)例在數(shù)據(jù)庫(kù)不存在梧却,會(huì)自動(dòng)生成并返回 HTTP 404 響應(yīng)。
自定義解析邏輯
如果你想要使用自定義的解析邏輯败去,需要使用 Route::bind
方法放航,傳遞到 bind
方法的閉包會(huì)獲取到 URI 請(qǐng)求參數(shù)中的值,并且返回你想要在該路由中注入的類實(shí)例:
public function boot()
{
parent::boot();
Route::bind('user', function($value) {
return App\User::where('name', $value)->first();
});
}
6圆裕、表單方法偽造
HTML 表單不支持 PUT
广鳍、PATCH
或者 DELETE
請(qǐng)求方法,因此吓妆,當(dāng)定義 PUT
赊时、PATCH
或 DELETE
路由時(shí),需要添加一個(gè)隱藏的 _method
字段到表單中行拢,其值被用作該表單的 HTTP 請(qǐng)求方法:
<form action="/foo/bar" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
還可以使用輔助函數(shù) method_field
來(lái)實(shí)現(xiàn)這一目的:
{{ method_field('PUT') }}
7祖秒、訪問(wèn)當(dāng)前路由
你可以使用 Route Facade
上的 current
、currentRouteName
和 currentRouteAction
方法來(lái)訪問(wèn)處理當(dāng)前輸入請(qǐng)求的路由信息:
$route = Route::current();
$name = Route::currentRouteName();
$action = Route::currentRouteAction();
參考API文檔了解路由門面底層類以及Route實(shí)例的更多可用方法舟奠。