lavaral中文手册_【laravel7.x中文文档】路由
路由
[TOC]
基本路由
構建基本路由只需要一個 URI 與一個 閉包 ,這里提供了一個非常簡單優雅定義路由的方法:
Route::get('foo', function () {
return 'Hello World';
});
默認路由文件
所有的 Laravel 路由都在 routes 目錄中的路由文件中定義,這些文件都由框架自動加載。routes/web.php 文件用于定義 web 界面的路由。這里面的路由都會被分配給 web 中間件組,它提供了會話狀態和 CSRF 保護等功能。定義在 routes/api.php 中的路由都是無狀態的,并且被分配了 api 中間件組。
大多數的應用構建,都是以在 routes/web.php 文件定義路由開始的。可以通過在瀏覽器中輸入定義的路由 URL 來訪問 routes/web.php 中定義的路由。例如,你可以在瀏覽器中輸入 http://your-app.dev/user 來訪問以下路由:
Route::get('/user', 'UserController@index');
routes/api.php 文件中定義的路由通過 RouteServiceProvider 被嵌套到一個路由組里面。在這個路由組中,會自動添加 URL 前綴 /api 到此文件中的每個路由,這樣你就無需再手動添加了。你可以在 RouteServiceProvider 類中修改此前綴以及其他路由組選項。
可用的路由方法
路由器允許你注冊能響應任何 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('/', function () {
//
});
CSRF 保護
指向 web 路由文件中定義的 POST、PUT 或 DELETE 路由的任何 HTML 表單都應該包含一個 CSRF 令牌字段,否則,這個請求將會被拒絕。可以在 CSRF 文檔 中閱讀有關 CSRF 更多信息:
@csrf
...
重定向路由
如果要定義重定向到另一個 URI 的路由,可以使用 Route::redirect 方法。這個方法可以快速的實現重定向,而不再需要去定義完整的路由或者控制器:
Route::redirect('/here', '/there');
Route::redirect 默認會返回狀態碼 302 。 你可以通過第三個參數自定義返回碼:
Route::redirect('/here', '/there', 301);
你也可以使用 Route::permanentRedirect 方法來返回 301 狀態碼:
Route::permanentRedirect('/here', '/there');
視圖路由
如果你的路由只需要返回一個視圖,可以使用 Route::view 方法。它和 redirect 一樣方便,不需要定義完整的路由或控制器。view 方法有三個參數,其中第一個是必填參數,是包含視圖名稱的 URI 。第二個也是必填參數,是需要渲染的視圖名稱。此外,還可以通過數組傳遞一組數據給視圖,作為可選的第三個參數:
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 = '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();
}
一旦定義好之后,便會自動應用這些規則到所有使用該參數名稱的路由上:
Route::get('user/{id}', function ($id) {
// 只有在 id 為數字時才執行
});
編碼正斜杠字符
Laravel 路由組件允許除 / 之外的所有字符。你必須使用 where 條件正則表達式顯式地允許 / 成為占位符的一部分:
Route::get('search/{search}', function ($search) {
return $search;
})->where('search', '.*');注意:編碼正斜杠字符僅在最后一個路由段中是支持的。
路由命名
路由命名可以方便地為指定路由生成 URL 或者重定向。通過在路由定義上鏈式調用 name 方法可以指定路由名稱:
Route::get('user/profile', function () {
//
})->name('profile');
你還可以指定控制器行為的路由名稱:
Route::get('user/profile', 'UserProfileController@show')->name('profile');
生成指定路由的 URL
為路由指定了名稱后,就可以使用全局輔助函數 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]);
如果在數組中傳遞額外的參數,這些 / 值將自動添加到生成的 URL 的查詢字符串中:
Route::get('user/{id}/profile', function ($id) {
//
})->name('profile');
$url = route('profile', ['id' => 1, 'photos' => 'yes']);
// /user/1/profile?photos=yesTip:有時,您可能希望為 URL 參數指定請求范圍的默認值,例如當前的 locale 。為此,可以使用 URL::defaults 方法 。
檢查當前路由
如果你想判斷當前請求是否指向了某個命名過的路由,你可以調用路由實例上的 named 方法。例如,你可以在路由中間件中檢查當前路由名稱:
/**
* 處理一個請求
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->route()->named('profile')) {
//
}
return $next($request);
}
路由組
路由組允許你在大量路由之間共享路由屬性,例如中間件或命名空間,而不需要為每個路由單獨定義這些屬性。共享屬性應該以數組的形式傳入 Route::group 方法的第一個參數中。
嵌套的組嘗試智能地「合并」其屬性及其父組。中間件和 where 條件語句在附加名稱、命名空間和前綴時被合并。在適當的情況下,命名空間的分隔符和斜線會被自動添加到 URI 前綴中。
中間件
要給路由組中所有的路由分配中間件,可以在 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 之后的部分。
子域名路由
路由組也可以用來處理子域名。子域名可以像路由 URI 一樣被分配路由參數,允許你獲取一部分子域名作為參數給路由或控制器使用。可以在定義 group 之前調用 domain 方法來指定子域名:
Route::domain('{account}.myapp.com')->group(function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});注意:為了確保您的子域名路由是可訪問的,您應該在注冊根域名路由之前注冊子域名路由。這將防止根域名路由覆蓋具有相同 URI 路徑的子域名路由。
路由前綴
可以用 prefix 方法為路由組中給定的 URL 增加前綴。例如,你可以為組中所有路由的 URI 加上 admin 前綴:
Route::prefix('admin')->group(function () {
Route::get('users', function () {
// 匹配包含 「/admin/users」 的 URL
});
});
路由名稱前綴
name 方法可以用來給路由組中的每個路由名稱添加一個給定的字符串。 例如,您可能希望以 admin 為所有分組路由的名稱加前綴。 給定的字符串與指定的路由名稱前綴完全相同,因此我們將確保在前綴中提供尾部的 . 字符:
Route::name('admin.')->group(function () {
Route::get('users', function () {
// 指定路由名為 「admin.users」...
})->name('users');
});
路由模型綁定
當向路由或控制器行為注入模型 ID 時,就需要查詢這個 ID 對應的模型。Laravel 為路由模型綁定提供了一個直接自動將模型實例注入到路由中的方法。例如,你可以注入與給定 ID 匹配的整個 User 模型實例,而不是注入用戶的 ID。
隱式綁定
Laravel 會自動處理定義在路由或控制器行為中,與類型提示的變量名相匹配的路由段名稱的 Eloquent 模型,例如:
Route::get('api/users/{user}', function (App\User $user) {
return $user->email;
});
在這個例子中,由于 $user 變量被類型提示為 Eloquent 模型App\User,變量名稱又與 URI 中的 {user} 匹配,因此,Laravel 會自動注入與請求 URI 中傳入的 ID 匹配的用戶模型實例。如果在數據庫中找不到對應的模型實例,將會自動生成 404 異常。
自定義鍵名
有時,您可能希望使用 id 以外的列來解析 Eloquent 模型。為此,您可以在路由參數定義中指定列:
Route::get('api/posts/{post:slug}', function (App\Post $post) {
return $post;
});
自定義鍵和作用域
有時,當在一個路由定義中隱式綁定多個 Eloquent 模型時,您可能需要限定第二個 Eloquent 模型的作用域,使它必須是第一個 Eloquent 模型的子模型。例如,考慮這樣一種情況,通過 slug 字段為特定用戶檢索博客文章:
use App\Post;
use App\User;
Route::get('api/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
});
當使用自定義鍵值隱式綁定作為嵌套路由參數時,Laravel 將自動限定查詢的范圍,通過其父節點使用猜測父節點上關系名稱的約定來檢索嵌套模型。在本例中,假定 User 模型有一個名為 posts 的關系(路由參數名的復數形式),可用于檢索 Post 模型。
自定義鍵名
如果您希望模型綁定在檢索給定模型類時使用 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 為 1 的 User 實例。
如果在數據庫中找不到匹配的模型實例,就會自動拋出一個 404 異常。
自定義解析邏輯
如果您希望使用自己的解析邏輯,則可以使用 Route::bind 方法。傳遞給 bind 方法的 閉包 將接收 URI 中大括號對應的值,并返回您想要在該路由中注入的類的實例:
/**
* 啟動任意應用服務
*
* @return void
*/
public function boot()
{
parent::boot();
Route::bind('user', function ($value) {
return App\User::where('name', $value)->firstOrFail();
});
}
或者,您可以重寫 Eloquent 模型上的 resolveRouteBinding 方法。 此方法會接受 URI 中大括號對應的值,并且返回你想要在該路由中注入的類的實例:
/**
* 檢索綁定值的模型
*
* @param mixed $value
* @param string|null $field
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveRouteBinding($value, $field = null)
{
return $this->where('name', $value)->firstOrFail();
}
回退路由
使用 Route::fallback 方法, 您可以定義一個在沒有其他路由可匹配傳入的請求時才執行的路由。一般來說,未處理的請求會通過應用程序的異常處理程序自動呈現 「404」 頁面。但是由于您可以在 routes/web.php 文件中定義 fallback 路由,因此 web 中間件組中的所有中間件都將應用于該路由。當然,您也可以根據需要隨意向此路由添加其他中間件:
Route::fallback(function () {
//
});{note} 回退路由應始終是您應用程序注冊的最后一個路由。
限流
Laravel 包含了一個中間件用于控制應用程序對路由的訪問。如果想要使用,請將 throttle 中間件分配給一個路由或者路由組。throttle 中間件會接收兩個參數,這兩個參數決定了在給定的分鐘數內可以進行的最大請求數。例如,指定一個經過身份驗證并且用戶每分鐘訪問頻率不超過 60 次的路由組:
Route::middleware('auth:api', 'throttle:60,1')->group(function () {
Route::get('/user', function () {
//
});
});
動態限流
您可以根據已驗證的 User 模型的屬性,指定動態請求的最大值。例如,如果您的 User 模型包含 rate_limit 屬性,則可以將屬性名稱傳遞給 throttle 中間件,以便它用于計算最大請求數:
Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
Route::get('/user', function () {
//
});
});
獨立訪客和認證用戶的限流
您可以為訪客和經過身份驗證的用戶指定不同的訪問控制。例如,可以為訪客設置每分鐘最多 10 次請求,為認證用戶設置每分鐘最多 60 次請求:
Route::middleware('throttle:10|60,1')->group(function () {
//
});
您還可以將此功能與動態限流相結合。例如,如果 User 模型包含一個 rate_limit 屬性,您可以將該屬性的名稱傳遞給 throttle 中間件,以便用于計算認證用戶的最大請求數:
Route::middleware('auth:api', 'throttle:10|rate_limit,1')->group(function () {
Route::get('/user', function () {
//
});
});
分段限流
通常,您可能會為整個 API 設置一個速率限制。但是,您的應用程序可能需要對 API 的不同部分設置不同的速率限制。如果是這種情況,則需要將片段名稱作為第三個參數傳遞給 throttle 中間件:
Route::middleware('auth:api')->group(function () {
Route::middleware('throttle:60,1,default')->group(function () {
Route::get('/servers', function () {
//
});
});
Route::middleware('throttle:60,1,deletes')->group(function () {
Route::delete('/servers/{id}', function () {
//
});
});
});
表單方法偽造
HTML 表單不支持 PUT、PATCH 或 DELETE 請求。所以當您需要從 HTML 表單中調用請求方式為 PUT、PATCH 或 DELETE 的路由時,您需要在表單中增加一個隱藏的 _method 輸入標簽。使用 _method 字段的值作為 HTTP 的請求方式:
您也可以使用 _method 隱藏域:
@method('PUT')
@csrf
訪問當前路由
您可以使用 Route 門面的 current,currentRouteName 以及 currentRouteAction 方法處理傳入的請求路由訪問信息:
$route = Route::current();
$name = Route::currentRouteName();
$action = Route::currentRouteAction();
有關 Route門面 和 Route實例 的 基礎類,請參閱 API 文檔,以查看所有可訪問的方法。
跨域資源共享 (CORS)
Laravel 可以使用您配置的值自動響應 CORS OPTIONS 請求。所有 CORS 設置都可以在 CORS 配置文件中配置,選項請求將由默認情況下包含在全局中間件中的 HandleCors 中間件自動處理。
{tip} 有關 CORS 和 CORS headers 的更多信息,請查閱有關 CORS 的 MDN Web 文檔。
總結
以上是生活随笔為你收集整理的lavaral中文手册_【laravel7.x中文文档】路由的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql实验四图书视图_[数据库实验四
- 下一篇: vue的post请求data可以传两个参