laravel 路由是開發(fā)人員從一開始就學(xué)習(xí)的特性。但是隨著他們項(xiàng)目的增長,管理不斷增長的路由文件變得越來越困難,經(jīng)常需要滾動查找正確的 Route::get() 語句。幸運(yùn)的是,有一些技術(shù)可以使路由文件更短、更易讀,讓我們來看看以不同的方式對路由及其設(shè)置進(jìn)行分組。
我們不會只談?wù)撘话愫唵蔚?Route::group(),那是初學(xué)者級別。 讓我們再深入一點(diǎn)。
分組 1. Route::resource 和 Route::apiResource
讓我們從房間里的大象開始:這可能是最常用的分組。如果您圍繞一個模型有一組典型的 CRUD 操作,則應(yīng)該將它們分組到 資源控制器
此類控制器包含 資源控制器(但可能更少):
- index()
- create()
- store()
- show()
- edit()
- update()
- destroy()
因此,如果您的路由集對應(yīng)于這些方法,請不要使用:
Route::get('books',?[BookController::class,?'index'])->name('books.index'); Route::get('books/create',?[BookController::class,?'create'])->name('books.create'); Route::post('books',?[BookController::class,?'store'])->name('books.store'); Route::get('books/{book}',?[BookController::class,?'show'])->name('books.show'); Route::get('books/{book}/edit',?[BookController::class,?'edit'])->name('books.edit'); Route::put('books/{book}',?[BookController::class,?'update'])->name('books.update'); Route::delete('books/{book}',?[BookController::class,?'destroy'])->name('books.destroy');
… 您可能只有一行:
Route::resource('books',?BookController::class);
如果您使用 API 項(xiàng)目,則不需要用于創(chuàng)建 / 編輯的可視化表單,因此您可以使用 apiResource() 的涵蓋 7 種方法中的 5 種不同語法:
Route::apiResource('books',?BookController::class);
此外,我建議您考慮資源控制器,即使您有 2-4 個方法,而不是完整的 7 個。只是因?yàn)樗3謽?biāo)準(zhǔn)命名約定 – 對于 URL、方法和路由名稱。 例如,在這種情況下,您不需要手動提供名稱:
Route::get('books/create',?[BookController::class,?'create'])->name('books.create'); Route::post('books',?[BookController::class,?'store'])->name('books.store'); //?相反,這里的名稱“books.create”和“books.store”是自動分配的 Route::resource('books',?BookController::class)->only(['create',?'store']);
分組 2. ?嵌套子路由組
當(dāng)然,一般的 資源控制器 大家都知道。 但對于更復(fù)雜的項(xiàng)目,一級分組可能還不夠。
實(shí)際示例:您希望授權(quán)路由與 auth 中間件進(jìn)行分組,但在內(nèi)部您需要分隔更多子組,例如管理員和簡單用戶。
Route::middleware('auth')->group(function()?{ ????Route::middleware('is_admin')->prefix('admin')->group(function()?{ ?????Route::get(...)?//?administrator?routes ????}); ????Route::middleware('is_user')->prefix('user')->group(function()?{ ?????Route::get(...)?//?user?routes ????}); });
分組 3. 將重復(fù)的中間件分組
如果你有很多中間件,有一些在路由組中重復(fù)出現(xiàn)怎么辦?
Route::prefix('students')->middleware(['auth',?'check.role',?'check.user.status',?'check.invoice.status',?'locale'])->group(function?()?{ ????//?...?學(xué)生路由 }); Route::prefix('managers')->middleware(['auth',?'check.role',?'check.user.status',?'locale'])->group(function?()?{ ????//?...?管理員路由 });
如您所見,有 5 個中間件,其中 4 個是重復(fù)的。因此,在 app/Http/Kernel.php 文件里,我們可以將這 4 個移動到單獨(dú)的中間件組中:
protected?$middlewareGroups?=?[ ????//?此組是?Laravel?默認(rèn)中間件組 ????'web'?=>?[ ????????AppHttpMiddlewareEncryptCookies::class, ????????IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class, ????????IlluminateSessionMiddlewareStartSession::class, ????????IlluminateViewMiddlewareShareErrorsFromSession::class, ????????AppHttpMiddlewareVerifyCsrfToken::class, ????????IlluminateRoutingMiddlewareSubstituteBindings::class, ????], ????//?此組是?Laravel?默認(rèn)中間件組 ????'api'?=>?[ ????????//?LaravelSanctumHttpMiddlewareEnsureFrontendRequestsAreStateful::class, ????????'throttle:api', ????????IlluminateRoutingMiddlewareSubstituteBindings::class, ????], ????//?這是我們新的中間件組 ????'check_user'?=>?[ ????????'auth', ????????'check.role', ????????'check.user.status', ????????'locale' ????], ];
所以將我們的中間件組命明為 check_user,現(xiàn)在我們可以縮寫路由:
Route::prefix('students')->middleware(['check_user',?'check.invoice.status'])->group(function?()?{ ????//?...?student?routes }); Route::prefix('managers')->middleware(['check_user'])->group(function?()?{ ????//?...?manager?routes });
分組 4. 同名控制器,不同命名空間
很常見的情況是,例如,為不同的用戶角色設(shè)置了 HomeController,例如 Admin/HomeController 和 User/HomeController。 如果在路由中使用完整路徑,它看起來像這樣:
Route::prefix('admin')->middleware('is_admin')->group(function?()?{ ????Route::get('home',?[AppHttpControllersAdminHomeController::class,?'index']); }); Route::prefix('user')->middleware('is_user')->group(function?()?{ ????Route::get('home',?[AppHttpControllersUserHomeController::class,?'index']); });
每個控制器都是用了完整的路徑這看上去很冗余,對吧? 這就是為什么許多開發(fā)人員更喜歡在路由列表中只包含 HomeController::class 并在頂部添加類似這樣的內(nèi)容:
use?AppHttpControllersAdminHomeController;
但是這里的問題是我們有相同的控制器類名! 所以,這行不通:
use?AppHttpControllersAdminHomeController; use?AppHttpControllersUserHomeController;
哪一個是「管理后臺」的控制器?好吧,一種方法是更改名稱并為其中之一分配別名:
use?AppHttpControllersAdminHomeController?as?AdminHomeController; use?AppHttpControllersUserHomeController; Route::prefix('admin')->middleware('is_admin')->group(function?()?{ ????Route::get('home',?[AdminHomeController::class,?'index']); }); Route::prefix('user')->middleware('is_user')->group(function?()?{ ????Route::get('home',?[HomeController::class,?'index']); });
但是,就個人而言,更改頂部類的名稱讓我很困惑,我喜歡另一種方法:為控制器的子文件夾添加一個命名空間():
Route::prefix('admin')->namespace('AppHttpControllersAdmin')->middleware('is_admin')->group(function?()?{ ????Route::get('home',?[HomeController::class,?'index']); ????//?...?Admin?命名空間中的其他控制器 }); Route::prefix('user')->namespace('AppHttpControllersUser')->middleware('is_user')->group(function?()?{ ????Route::get('home',?[HomeController::class,?'index']); ????//?...?來自用戶命名空間的其他控制器 });
分組 5. 分離路由文件
如果你覺得 routes/web.php 或 routes/api.php 太大了,可以把一些路由放到一個單獨(dú)的文件中,你可以為它任意命名,例如 routes/admin.php。
要加載該文件,有兩種方法:我稱之為 「Laravel 方式」 和 「PHP 方式」 。
如果你想遵循 Laravel 構(gòu)建其默認(rèn)路由文件的結(jié)構(gòu),查看 app/Providers/RouteServiceProvider.php :
public?function?boot() { ????$this->configureRateLimiting(); ????$this->routes(function?()?{ ????????Route::middleware('api') ????????????->prefix('api') ????????????->group(base_path('routes/api.php')); ????????Route::middleware('web') ????????????->group(base_path('routes/web.php')); ????}); }
routes/api.php 和 routes/web.php 都在這里,但設(shè)置略有不同。因此,你只需要在此處添加 admin 文件:
$this->routes(function?()?{ ????Route::middleware('api') ????????->prefix('api') ????????->group(base_path('routes/api.php')); ????Route::middleware('web') ????????->group(base_path('routes/web.php')); ????Route::middleware('is_admin') ????????->group(base_path('routes/admin.php')); });
如果你不想深入研究 資源控制器,還有一種更簡單的方法 – 只需 include/require 您的路由文件到另一個文件中,就像你在 Laravel 框架之外的任何 PHP 文件。
事實(shí)上,這是由 Taylor Otwell 完成的,只需將 routes/auth.php 文件直接放入 資源控制器:
routes/web.php:
Route::get('/',?function?()?{ ????return?view('welcome'); }); Route::get('/dashboard',?function?()?{ ????return?view('dashboard'); })->middleware(['auth'])->name('dashboard'); require?__DIR__.'/auth.php';
分組 6. Laravel 9 中的新功能: Route::controller ()
如果你的 Controller 中有一些方法,但它們不遵循標(biāo)準(zhǔn)的 Resource 結(jié)構(gòu),您仍然可以對它們進(jìn)行分組,而無需為每個方法重復(fù) Controller 名稱。
取而代之的是:
Route::get('profile',?[ProfileController::class,?'getProfile']); Route::put('profile',?[ProfileController::class,?'updateProfile']); Route::delete('profile',?[ProfileController::class,?'deleteProfile']);
您可以這樣做:
Route::controller(ProfileController::class)->group(function()?{ ????Route::get('profile',?'getProfile'); ????Route::put('profile',?'updateProfile'); ????Route::delete('profile',?'deleteProfile'); });
此功能在 Laravel 9 和 Laravel 8 的最新小版本中可用。
就是這樣,這些分組技術(shù)有望幫助你組織和維護(hù)的路由,無論你的項(xiàng)目發(fā)展到多大。
原文地址:https://laravel-news.com/laravel-route-organization-tips譯文地址:https://learnku.com/laravel/t/68476
【相關(guān)推薦:資源控制器】