掌握 Laravel 路由
已發表: 2022-12-12說到後端,開發者最終都會遇到路由。 路由可以被認為是後端的骨幹,因為服務器收到的每個請求都通過將請求映射到控制器或操作的路由列表重定向到控制器。
Laravel 為我們隱藏了許多實現細節,並附帶了大量語法糖來幫助新手和有經驗的開發人員開發他們的 Web 應用程序。
讓我們仔細看看如何在 Laravel 中管理路由。
Laravel 中的後端路由和跨站腳本
在一台服務器上,既有公有路由,也有私有路由。 由於跨站點腳本 (XSS) 的可能性,公共路由可能引起關注,這是一種注入攻擊,可能使您和您的用戶容易受到惡意行為者的攻擊。
問題在於,用戶可以從不需要會話令牌的路由重定向到需要會話令牌的路由——他們仍然可以在沒有令牌的情況下訪問。
解決此問題的最簡單方法是強制執行新的 HTTP 標頭,將“referrer”添加到路由以緩解這種情況:
'main' => [ 'path' => '/main', 'referrer' => 'required,refresh-empty', 'target' => Controller\DashboardController::class . '::mainAction' ]
Laravel 基本路由
在 Laravel 中,路由允許用戶將適當的請求路由到所需的控制器。 最基本的 Laravel 路由接受一個統一資產標識符(你的路由路徑)和一個可以是函數或類的閉包。
在 Laravel 中,路由是在web.php和api.php文件中創建的。 Laravel 默認自帶兩種路由:一種用於 WEB,一種用於 API。
這些路由位於routes/文件夾中,但它們加載在Providers/RouteServiceProvider.php中。
我們可以直接在RouteServiceProvider.php中加載路由,而不是這樣做,完全跳過routes/文件夾。
重定向
當我們定義一個路由時,我們通常會想要重定向訪問它的用戶,而這樣做的原因多種多樣。 這可能是因為它是一個已棄用的路由,我們已經更改了後端或服務器,或者可能是因為我們想要安裝雙因素身份驗證 (2FA),等等。
Laravel 有一個簡單的方法可以做到這一點。 由於框架的簡單性,我們可以在 Route facade 上使用 redirect 方法,它接受入口路由和要重定向到的路由。
或者,我們可以將重定向的狀態代碼作為第三個參數。 permanentRedirect
方法將與redirect
方法做同樣的事情,除了它總是返回 301 狀態代碼:
// Simple redirect Route::redirect("/class", "/myClass"); // Redirect with custom status Route::redirect("/home", "/office", 305); // Route redirect with 301 status code Route::permanentRedirect("/home", "office");
在重定向路由中,我們禁止使用“destination”和“status”關鍵字作為參數,因為它們被 Laravel 保留。
// Illegal to use Route::redirect("/home", "/office/{status}");
觀點
意見是。 我們用來呈現 Laravel 應用程序前端的blade.php文件。 它使用 blade 模板引擎,它是僅使用 Laravel 構建全棧應用程序的默認方式。
如果我們希望我們的路由返回一個視圖,我們可以簡單地使用 Route facade 上的 view 方法。 它接受路由參數、視圖名稱和要傳遞給視圖的可選值數組。
// When the user accesses my-domain.com/homepage // the homepage.blade.php file will be rendered Route::view("/homepage", "homepage");
假設我們的視圖想通過傳遞一個帶有該參數的可選數組來說“你好, {name}
”。 我們可以使用以下代碼來做到這一點(如果視圖中需要缺少的參數,請求將失敗並拋出錯誤):
Route::view('/homepage', 'homepage', ['name' => "Kinsta"]);
路線列表
隨著應用程序規模的增長,需要路由的請求數量也會增加。 大量的信息會帶來巨大的混亂。
這是artisan route:list command
可以幫助我們的地方。 它概述了應用程序中定義的所有路由、它們的中間件和控制器。
php artisan route:list
它將顯示沒有中間件的所有路由列表。 為此,我們必須使用-v
標誌:
php artisan route:list -v
在您可能使用域驅動設計的情況下,您的路由在其路徑中具有特定名稱,您可以像這樣使用此命令的過濾功能:
php artisan route:list –path=api/account
這將僅顯示以api/account開頭的路由。
另一方面,我們可以使用–except-vendor
或–only-vendor
選項指示 Laravel 排除或包含第三方定義的路由。
路由參數
有時您可能需要使用路由捕獲 URI 的片段,例如用戶 ID 或令牌。 我們可以通過定義一個路由參數來做到這一點,該參數始終包含在花括號 ( {}
) 中並且應該只包含字母字符。
如果我們的路由在回調中有依賴,Laravel 服務容器會自動注入它們:
use Illuminate\Http\Request; use Controllers/DashboardController; Route::post('/dashboard/{id}, function (Request $request, string $id) { return 'User:' . $id; } Route::get('/dashboard/{id}, DashboardController.php);
必需參數
Laravel 的必參是路由中的參數,我們在調用的時候不允許跳過。 否則,將拋出錯誤:
Route::post("/gdpr/{userId}", GetGdprDataController.php");
現在在GetGdprDataController.php中,我們可以直接訪問$userId參數。
public function __invoke(int $userId) { // Use the userId that we received… }
路由可以採用任意數量的參數。 它們根據它們列出的順序被注入到路由回調/控制器中:
// api.php Route::post('/gdpr/{userId}/{userName}/{userAge}', GetGdprDataController.php); // GetGdprDataController.php public function __invoke(int $userId, string $userName, int $userAge) { // Use the parameters… }
可選參數
如果我們想在路由上只提供一個參數而沒有其他任何東西,而不影響整個應用程序,我們可以添加一個可選參數。 這些可選參數由?
附加到他們:
Route::get('/user/{age?}', function (int $age = null) { if (!$age) Log::info("User doesn't have age set"); else Log::info("User's age is " . $age); } Route::get('/user/{name?}', function (int $name = "John Doe") { Log::info("User's name is " . $name); }
路由通配符
Laravel 為我們提供了一種方法來過濾我們的可選或必需參數應該是什麼樣子。
假設我們想要一個用戶 ID 字符串。 我們可以使用where
方法在路由級別上像這樣驗證它。
where
方法接受參數名稱和將應用於驗證的正則表達式規則。 默認情況下,它接受第一個參數,但如果我們有很多,我們可以傳遞一個數組,以參數名稱作為鍵,規則作為值,Laravel 會為我們解析它們:
Route::get('/user/{age}', function (int $age) { // }->where('age', '[0-9]+'); Route::get('/user/{age}', function (int $age) { // }->where('[0-9]+'); Route::get('/user/{age}/{name}', function (int $age, string $name) { // }->where(['age' => '[0-9]+', 'name' => '[az][Az]+');
我們可以更進一步,通過在Route
facade 上使用pattern
方法對我們應用程序中的所有路由應用驗證:
Route::pattern('id', '[0-9]+');
這將使用此正則表達式驗證每個id
參數。 一旦我們定義它,它將自動應用到所有使用該參數名稱的路由。
如我們所見,Laravel 使用/
字符作為路徑中的分隔符。 如果我們想在路徑中使用它,我們必須使用where
正則表達式明確允許它成為我們佔位符的一部分。
Route::get('/find/{query}', function ($query) { // })->where('query', , '.*');
唯一的缺點是它只會在最後一個路線段中得到支持。
命名路由
顧名思義,我們可以為路由命名,這樣可以方便地為特定路由生成 URL 或重定向。
如何創建命名路由
鏈接在Route
facade 上的name
方法提供了一種創建命名路由的簡單方法。 每條路線的名稱應該是唯一的:
Route::get('/', function () { })->name("homepage");
路由組
路由組允許您在大量路由之間共享路由屬性(如中間件),而無需在每條路由上重新定義它。
中間件
為我們擁有的所有路由分配一個中間件允許我們將它們組合成一個組,首先使用group
方法。 需要考慮的一件事是中間件按照它們應用於組的順序執行:
Route:middleware(['AuthMiddleware', 'SessionMiddleware'])->group(function () { Route::get('/', function() {} ); Route::post('/upload-picture', function () {} ); });
控制器
當一個組使用相同的控制器時,我們可以使用controller
方法為該組內的所有路由定義公共控制器。 現在我們必須指定路由將調用的方法。
Route::controller(UserController::class)->group(function () { Route::get('/orders/{userId}', 'getOrders'); Route::post('/order/{id}', 'postOrder'); });
子域路由
子域名是添加到網站域名開頭的一段附加信息。 這允許網站為特定功能(例如在線商店、博客、演示文稿等)與網站的其餘部分分離和組織其內容。
我們的路由可用於處理子域路由。 我們可以捕獲域和子域的一部分,以便在我們的控制器和路由中使用。 在Route
facade 上的domain
方法的幫助下,我們可以將我們的路由分組在一個域下:
Route::domain('{store}.enterprise.com')->group(function() { Route::get('order/{id}', function (Account $account, string $id) { // Your Code } });
前綴和名稱前綴
每當我們有一組路由時,我們可以利用 Laravel 提供的額外實用程序,例如Route
facade 上的prefix
和name
,而不是一個接一個地修改它們。
prefix
方法可用於為組中的每個路由添加給定 URI 前綴, name
方法可用於為每個路由名稱添加給定字符串前綴。
這允許我們創建新的東西,比如管理路由,而不需要修改每個名稱或前綴來識別它們:
Route::name('admin.")->group(function() { Route::prefix("admin")->group(function() { Route::get('/get')->name('get'); Route::put('/put')->name(put'); Route::post('/post')->name('post'); }); });
現在這些路由的 URI 將是admin/get
、 admin/put
、 admin/post
以及名稱admin.get
、 admin.put
和admin.post
。
路由緩存
將應用程序部署到生產服務器時,優秀的 Laravel 開發人員會利用 Laravel 的路由緩存。
什麼是路由緩存?
路由緩存減少了註冊所有應用程序路由所需的時間。
運行php artisan route:cache
會生成一個Illuminate/Routing/RouteCollection
的實例,經過編碼後,序列化後的輸出會寫入bootstrap/cache.routes.php
。
現在任何其他請求都將加載此緩存文件(如果存在)。 因此,我們的應用程序不再需要將路由文件中的條目解析並轉換為Illuminate/Routing/Route
Illuminate/Routing/RouteCollection
Route 對象。
為什麼使用路由緩存很重要
如果不使用 Laravel 提供的路由緩存功能,您的應用程序可能會運行得比預期的慢,這反過來可能會降低銷售額、用戶保留率和對您品牌的信任度。
根據項目的規模和路由的數量,運行一個簡單的路由緩存命令可以將應用程序的速度提高 130% 到 500%——這是一個幾乎不費吹灰之力的巨大收穫。
概括
路由是後端開發的支柱。 Laravel 框架在這方面表現出色,它提供了一種定義和管理路由的冗長方式。
確實每個人都可以進行開發,並且僅僅因為它是在 Laravel 中構建的,就可以幫助加速應用程序。
關於 Laravel 路由,你還遇到過哪些其他技巧和技巧? 請在評價部分留下您的意見!