基本路由php
構建最基本的路由只須要一個URL與一個閉包,這裏提供了一個很是簡單優雅的定義路由的方法:web
Route::get('foo',function(){正則表達式
return 'Hello World';數據庫
});api
默認路由文件數組
全部的Laravel路由都在 routes目錄中路由文件中定義,這些文件都由框架自動加載,routes/web.php 文件用於定義web界面的路由。這裏面的路由都會被分配給 web 中間件,它提供了回話狀態和CSRF保護等功能。定義在瀏覽器
routes/api.php 中的路由都是無狀態的,而且分配了api中間件組。閉包
大多數的應用構建,都是以在 routes/web.php 文件定義路由開始的。能夠經過在瀏覽器中輸入定義的路由URL來訪問 routes/web.php 中定義的路由。例如,你能夠在瀏覽器中輸入 http://your-app.dev/user 來訪問一下路由:app
Route::get('/user','UsersController@index');框架
routes/api.php 文件中定義的路由經過 RoutesSericeProvider 被嵌套到一個路由組裏面。在這個路由組中,會自動添加URL 前綴 /api 到此文件中的每一個路由,這樣你就無需再手動添加了,你能夠在RouteServiceProvider 類中修改此前綴以及其餘路由組選項。
可用的路由方法
路由器容許你註冊能響應任何HTTP請求的路由:
Route::get($uri,$callback);
Route::post($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 路由文件中 定義的 POST 、 PUT 或 DELETE 路由的任何HTML 表單都應該包含一個 CSRF 令牌字段,不然,這個請求將會拒絕。能夠在 CSRF 文檔中閱讀有關 CSRF 保護的更多信息:
<form method="POST" action="/profile">
{{ csrf_field() }}
...
</form>
重定向路由#
若是要定義重定向到另外一個URL的路由,可使用 Route::redirect 方法。這個方法能夠快速地實現重定向,而再也不須要去定義完整的路由或者控制器 。
Route::redirect('/here',‘/there’,301);
視圖路由#
若是你的路由只須要返回一個試圖,可使用 Route::view 方法。 它和 redirect 同樣方便,不須要定義完整的路由或控制器。view 方法有三個參數,其中前兩個是必填參數,分別是URL和視圖名稱。第三個參數選填,能夠傳入一個數組,數組中的數據會被傳遞給視圖。
Route::view('/welcome','welcome');
Route::view('/welcome','welcome',['name'=>'Taylor']);
路由參數#
必填參數#
固然,有時須要在路由中捕獲一些URL片斷。例如,從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 = 'johm'){
return $name;
});
正則表達式約束#
你可使用路由實例上 where 方法約束路由參數的格式。 where 方法接受參數名稱和定義參數應如何約束的正則表達式:
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]+']);
全局約束#
若是你但願某個具體的路由參數都遵循同一個正則表達式的約束,就使用 pattern 方法在 RouteServiceProvider
的 boot 方法中定義這些模式:
/*
* 定義你的路由模式綁定,pattern 過濾器等。
@return void
*/
public function boot()
{
Route::pattern('id','[0-9]+');
parent::boot();
}
定義好以後,變會自動應用到全部使用該參數名稱的路由上:
Route::get('user/{id}',function($id){
// 僅在 {id} 爲數字時執行。。。。
});
命名路由
命名路由能夠方便地爲制定路由生成 URL 或者重定向。經過在路由定義上鍊式調用 那麼 方法制定路由名稱:
Route::get('user/profile',function(){
//
})->name('profile');
你還能夠指定控制器行爲的路由名稱:
Route::get('user/profile','UserController@showProfile')->name('profile');
爲命名路由生成連接#
爲路由指定了名稱後,就可使用全局輔助函數 route 來生成連接或者重定向到該路由:
// 生成 URL ...
$url = route('profile');
// 生成重定向....
return redirect()->route('profile');
若是是有定義參數的命名路由,能夠把參數做爲 route函數的第二個參數傳入,指定的參數將會自動插入到URL中,對應的位置:
Route::get('user/{id}/profile',function($id){
//
})->name('profile');
$url = route('profile',['id' => 1]);
檢查當前路由#
若是你想判斷當前請求是否指向了某個路由,你能夠調用路由實例上的 named 方法。 例如,你能夠在路由中間件檢查當前路由名稱:
/**
處理一次請求。
@param \Illuminate\Http\Request $request
@param \Closure $next
@retrun mixed
*/
public function handle($request, Closure $next)
{
if ($request->route()->named('profile')){
//
}
return $next($request);
}
路由組#
路由組容許你在大量路由之間共享路由屬性,例如中間件或命名空間,而不須要爲每一個路由單獨定義這些屬性。共享屬性應該以數組的形式傳入 Route::group 方法的第一個參數中。
中間件#
要給路由組中全部的路由分配中間件,能夠在 group 以前調用 middleware 方法.中間件會依照它們在數組中列出的順序來運行:
Route::middleware(['first','second'])->group(function(){
Route::get('/',function(){
// 使用 first 和 second 中間件
});
Route::get('user/profile',function(){
// 使用 first 和 second 中間件
});
});
命名空間#
另外一個常見用例是使用 namespace 方法將相同的 PHP 命名空間分配給路由組的中全部的控制器:
Route::namespace('Admin')->group(function(){
// 在 "App\Http\Controllers\Admin" 命名空間下的控制器
});
請記住,默認狀況下,RouteServiceProvider 會在命名空間組中引入你的路由文件,讓你不用指定完整的
App/Http/Controllers 命名空間前綴就能註冊控制器路由。所以,你只須要指定命名空間
App\Http\Controllers 以後的部分。
子域名路由#
路由組也能夠用來處理子域名。子域名能夠像路由URL同樣被分配路由參數,容許你獲取一部分域名做爲參數給路由或控制器使用。 能夠在 group 以前調用 domain 方法來指定子域名:
Route::domain('{account}.myapp.com')->group(function(){
Route::get('user/{id}',function($account,$id){
//
});
});
路由前綴#
能夠用 prefix 方法爲路由中給定的URL增長前綴。例如,你能夠爲組中全部路由的URL加上 admin 前綴:
Rounte::prefix('admin')->group(function(){
Route::get('users',function(){
//匹配包括 "/admin/users" 的 URL
});
});
路由模型綁定#
當向路由或控制器行爲注入模型ID時,就須要查詢這個ID對應的模型。Laravel 爲路由模型綁定提供了一個直接自動將模型實例注入到路由中的方法,例如,你能夠注入與給定ID匹配的整個User 模型實例,而不是注入用戶的ID.
隱式綁定#
Laravlel 會自動解析定義在路由或控制器行爲中與類型提示的變量名匹配的路由段名稱的Eloquent 模型.例如:
Route::get('api/users/{user}',function(App\User $user){
return $user->email;
});
在這個例子中,因爲 $user 變量被類型提示爲 Eloquent 模型 App\User , 變量名稱又與URL中的{$user}匹配,
所以,Laravel 會自動注入與請求URL中傳入的ID 匹配的用戶模型實例。若是在數據庫中找不到對應的模型實例,將會自動生成404異常。
自定義鍵名#
若是你想要模型綁定在檢索給定的模型類時使用除id以外的數據庫字段,你能夠在Eloquent模型上重寫
getRouteKeyName 方法:
/*
爲路由模型獲取鍵名
@return string
*/
public function getRouteKeyName()
{
return 'slug';
}
顯示綁定#
要註冊顯示綁定,使用路由器的model 方法來爲給定參數指定類。在 RouteServiceProvider 類中的boot 方法
內定義這些顯示模型綁定:
public function boot()
{
parent::boot();
Route::model('user',App\User::class);
}
接着,定義一個包含{user} 參數的路由:
Route::get('profile/{user}',function(App\User $user){
//
});
由於咱們已經將全部{$user} 參數綁定至App\User 模型,因此 User 實例將被注入該路由。例如,
profile/1 的請求會注入數據庫中ID的數據,就會自動拋出一個404異常。
自定義解析邏輯#
若是你想要使用自定義的解析邏輯,就使用 Route::bind 方法。傳遞到bind 方法的閉包會接受URL 中大括號對應的值,而且返回你想要在該路由中注入的類的實例:
public function boot()
{
parent::boot();
Route::bind('user',.function($value){
return App\user::where('name',$value)->first();
})
}
表單方法僞造#
HTML 表單不支持 PUT PATCH 或 DELETE 行爲。因此當你要從HTML 表單中調用了 PUT .PATH 或 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')}}
訪問當前路由#
你可使用Route Facade 上的current currentRouteName 和 currentRouteAction 方法來訪問處理傳入請求的路由的信息:
$route = Route::current();
$name = Route::currentRouteName();
$action = Route::currentRouteAction();