* * * * *
[TOC]
## 基本路由
構建最基本的路由只需要一個 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`?中?`POST`,?`PUT`?或?`DELETE`?路由的 HTML 表單請求都應該包含一個 CSRF 令牌,否則,這個請求將會被拒絕。更多的關于 CSRF 的說明在?[CSRF 說明文檔](CSRF保護.md):
~~~
<form method="POST" action="/profile">
{{ csrf_field() }}
...
</form>
~~~
## 路由參數
### 必選路由參數
當然,有時我們需要在路由中捕獲一些 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 = 'John') {
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();
}
~~~
Pattern 一旦被定義,便會自動應用到所有使用該參數名稱的路由上:
~~~
Route::get('user/{id}', function ($id) {
// 僅在 {id} 為數字時執行...
});
~~~
## 命名路由
命名路由可以方便的生成?`URL`?或者重定向到指定的路由,你可以在定義路由后使用?`name`?方法實現:
~~~
Route::get('user/profile', function () {
//
})->name('profile');
~~~
你還可以為控制器方法指定路由名稱:
~~~
Route::get('user/profile', 'UserController@showProfile')->name('profile');
~~~
#### 為命名路由生成?`URL`
為路由指定了名稱后,我們可以使用全局輔助函數?`route`?來生成?`URL`?或者重定向到該條路由:
~~~
// 生成 URL...
$url = route('profile');
// 生成重定向...
return redirect()->route('profile');
~~~
如果是有定義參數的命名路由,可以把參數作為?`route`?函數的第二個參數傳入,指定的參數將會自動插入到?`URL`?中對應的位置:
~~~
Route::get('user/{id}/profile', function ($id) {
//
})->name('profile');
$url = route('profile', ['id' => 1]);
~~~
## 路由組
路由組允許共享路由屬性,例如中間件和命名空間等,我們沒有必要為每個路由單獨設置共有屬性,共有屬性會以數組的形式放到?`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 () {
// 在 "App\Http\Controllers\Admin" 命名空間下的控制器
});
~~~
請記住,默認?`RouteServiceProvider`?會在命名空間組中引入你的路由文件,讓你不用指定完整的?`App\Http\Controllers`?命名空間前綴就能注冊控制器路由,因此,我們在定義的時候只需要指定命名空間?`App\Http\Controllers`?以后的部分。
### 子域名路由
路由組也可以用作子域名的通配符,子域名可以像 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
});
});
~~~
## 路由模型綁定
當向路由控制器中注入模型 ID 時,我們通常需要查詢這個 ID 對應的模型,Laravel 路由模型綁定提供了一個方便的方法自動將模型注入到我們的路由中,例如,除了注入一個用戶的 ID,你也可以注入與指定 ID 匹配的完整?`User`?類實例。
### 隱式綁定
Laravel 會自動解析定義在路由或控制器方法(方法包含和路由片段匹配的已聲明類型變量)中的 Eloquent 模型,例如:
~~~
Route::get('api/users/{user}', function (App\User $user) {
return $user->email;
});
~~~
在這個例子中,由于類型聲明了 Eloquent 模型?`App\User`,對應的變量名?`$user`?會匹配路由片段中的?`{user}`,這樣,Laravel 會自動注入與請求 URI 中傳入的 ID 對應的用戶模型實例。
如果數據庫中找不到對應的模型實例,將會自動生成產生一個 404 HTTP 響應。
#### 自定義鍵名
如果你想要隱式模型綁定除?`id`?以外的數據庫字段,你可以重寫 Eloquent 模型類的?`getRouteKeyName`?方法:
~~~
/**
* 為路由模型獲取鍵名
*
* @return string
*/
public function getRouteKeyName()
{
return 'slug';
}
~~~
### 顯式綁定
使用路由的?`model`?方法來為已有參數聲明 class 。你應該在?`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 為 1 的?`User`?實例。
> **注意:**如果在數據庫不存在對應 ID 的數據,就會自動拋出一個 404 異常。
#### 自定義解析邏輯
如果你想要使用自定義的解析邏輯,需要使用?`Route::bind`?方法,傳遞到?`bind`?方法的閉包會獲取到 URI 請求參數中的值,并且返回你想要在該路由中注入的類實例:
~~~
public function boot()
{
parent::boot();
Route::bind('user', function ($value) {
return App\User::where('name', $value)->first();
});
}
~~~
## 表單方法偽造
HTML 表單沒有支持?`PUT`、`PATCH`?或?`DELETE`?動作。所以在定義要在 HTML 表單中調用的?`PUT`、`PATCH`?或?`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`?上的?`current`,?`currentRouteName`, and?`currentRouteAction`?方法來訪問處理當前輸入請求的路由信息:
~~~
$route = Route::current();
$name = Route::currentRouteName();
$action = Route::currentRouteAction();
~~~
完整的方法列表請參考?[Route facade](http://laravel.com/api/laravel/5.4/Illuminate/Routing/Router.html)?和?[Route 實例](http://laravel.com/api/laravel/5.4/Illuminate/Routing/Route.html)
- 前言
- 翻譯說明
- 發行說明
- 升級說明
- 貢獻導引
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- 請求周期
- 開發環境部署
- Homestead
- Valet
- 核心概念
- 服務容器
- 服務提供者
- Facades
- Contracts
- HTTP層
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- Session
- 表單驗證
- 前端
- Blade 模板
- 本地化
- 前端指南
- 編輯資源 Mix
- 安全
- 用戶認證
- Passport OAuth 認證
- 用戶授權
- 加密解密
- 哈希
- 重置密碼
- 綜合話題
- Artisan 命令行
- 廣播系統
- 緩存系統
- 集合
- 錯誤與日志
- 事件系統
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 模型關聯
- Eloquent 集合
- 修改器
- 序列化
- 測試
- 快速入門
- HTTP 測試
- 瀏覽器測試 Dusk
- 數據庫測試
- 測試模擬器
- 官方擴展包
- Cashier 交易工具包
- Envoy 部署工具
- Scout 全文搜索
- Socialite 社會化登錄