原文連接: https://learnku.com/laravel/t...
討論請前往專業的 Laravel 開發者論壇: https://learnku.com/Laravel
想象一下一個擁有 100 多個路由的 Laravel 項目,其中包括訪客,用戶,管理員等分離的模塊。你真的要將全部內容寫在在一個文件中嗎?那麼如何將它們分組,而且爲 URL 添加前綴呢?看看有哪些辦法。php
這個簡單,由於 Laravel 已經幫你作了。有以下兩個文件:前端
所以,若是你的項目同時具備前端頁面和 API (使用場景愈來愈廣),請把 API 的路由放在 api.php 裏。laravel
例如,若是你有 /users 頁面,又有 /api/users/ 端點,把他們分別寫在本身屬於本身路由文件裏,以避免在同一文件中出現同一相同名稱而產生混淆。git
但我最近仍是從 官方 Laravel 項目中看到了反例。在 Laravel Horizon 中,Taylor 只有 API 路由,但他沒有分開寫,仍是寫在了 routes/web.php :github
另外一個例子證實 Laravel 仍是很是的我的化,甚至 Taylor 本身也沒有 100% 按照標準來。web
下面例子也是來自 Laravel 官方文檔 的示例:api
Route::middleware(['first', 'second'])->group(function () { Route::get('/', function () { // 使用 first 和 second 中間件 }); Route::get('user/profile', function () { // 使用 first 和 second 中間件 }); });
最基本的用法是將不一樣的路由分組包含在不一樣的中間件裏面。例如,你但願一個組默認受 auth 中間件限制,另外一組受單獨的 admin 自定義中間件限制等。數組
這樣,你還可使用 名稱 和 前綴 等路由分組方法。一樣,官方文檔中給出了示例:app
Route::prefix('admin')->group(function () { Route::get('users', function () { // 匹配 URL 「/admin/users」 }); }); Route::name('admin.')->group(function () { Route::get('users', function () { // 路由名爲 「admin.users」... })->name('users'); });
另外,若是您要將全部中間件 + 名稱 + 前綴添加到一個組中,則將它們放入數組中更容易理解:ide
// 而不是這樣作: Route::name('admin.')->prefix('admin')->middleware('admin')->group(function () { // ... }); // 可使用數組 Route::group([ 'name' => 'admin.', 'prefix' => 'admin', 'middleware' => 'auth' ], function () { // ... });
咱們將其結合爲一個擁有三個路由分組的真實示例:
如下是將全部內容分組到 routes / web.php 文件中的一種方法:
Route::group([ 'name' => 'admin.', 'prefix' => 'admin', 'middleware' => 'admin' ], function () { // URL連接:/admin/users // 路由名稱:admin.users Route::get('users', function () { return 'Admin: user list'; })->name('users'); }); Route::group([ 'name' => 'user.', 'prefix' => 'user', 'middleware' => 'auth' ], function () { // URL連接:/user/profile // 路由名稱:user.profile Route::get('profile', function () { return 'User profile'; })->name('profile'); }); Route::group([ 'name' => 'front.', 'prefix' => 'front' ], function () { // 這裏沒有中間件 // URL連接:/front/about-us // 路由名稱:front.about Route::get('about-us', function () { return 'About us page'; })->name('about'); });
在上面的例子中,咱們沒有使用控制器,只是返回了靜態文本做爲示例。 讓咱們添加一個控制器,來點小花樣 — 咱們會將它們構造到各自不一樣的命名空間的文件夾中,以下所示:
而後咱們能夠在路由文件中使用它們:
Route::group([ 'name' => 'front.', 'prefix' => 'front' ], function () { Route::get('about-us', 'Front.boutController@index')->name('about'); });
可是若是在這個組中咱們有不少控制器呢? 咱們應該一直添加Front.omeController 嗎? 固然不是。您也能夠將命名空間做爲參數之一。
Route::group([ 'name' => 'front.', 'prefix' => 'front', 'namespace' => 'Front', ], function () { Route::get('about-us', 'AboutController@index')->name('about'); Route::get('contact', 'ContactController@index')->name('contact'); });
上面的狀況,分爲了3個組,實際上這是被簡化的, 實際項目的結構稍有不一樣 – 是 兩 個組:front 和 auth 。 而後在 auth 中,有兩個子組:user 和 admin 。爲此, 咱們能夠在 routes/web.php中建立子組,並分配不一樣的中間件/前綴等。
Route::group([ 'middleware' => 'auth', ], function() { Route::group([ 'name' => 'admin.', 'prefix' => 'admin', 'middleware' => 'admin' ], function () { // URL: /admin/users // Route name: admin.users Route::get('users', 'UserController@index')->name('users'); }); Route::group([ 'name' => 'user.', 'prefix' => 'user', ], function () { // URL: /user/profile // Route name: user.profile Route::get('profile', 'ProfileController@index')->name('profile'); }); });
咱們甚至能夠多層嵌套,這是開源項目的一個示例。 Akaunting:
Route::group(['middleware' => 'language'], function () { Route::group(['middleware' => 'auth'], function () { Route::group(['prefix' => 'uploads'], function () { Route::get('{id}', 'Common.ploads@get'); Route::get('{id}/show', 'Common.ploads@show'); Route::get('{id}/download', 'Common.ploads@download'); }); Route::group(['middleware' => 'permission:read-admin-panel'], function () { Route::group(['prefix' => 'wizard'], function () { Route::get('/', 'Wizard.ompanies@edit')->name('wizard.index'); // ...
另外一個例子來自另外一個流行的Laravel CRM,名爲Monica:
Route::middleware(['auth', 'verified', 'mfa'])->group(function () { Route::name('dashboard.')->group(function () { Route::get('/dashboard', 'DashboardController@index')->name('index'); Route::get('/dashboard/calls', 'DashboardController@calls'); Route::get('/dashboard/notes', 'DashboardController@notes'); Route::get('/dashboard/debts', 'DashboardController@debts'); Route::get('/dashboard/tasks', 'DashboardController@tasks'); Route::post('/dashboard/setTab', 'DashboardController@setTab'); });
有一個服務於全部路由設置的文件 – app/Providers/RouteServiceProvider.php. 它具備綁定兩個路由文件 – web 和 API 的 map() 方法:
public function map() { $this->mapApiRoutes(); $this->mapWebRoutes(); } protected function mapWebRoutes() { Route::middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web.php')); } protected function mapApiRoutes() { Route::prefix('api') ->middleware('api') ->namespace($this->namespace) ->group(base_path('routes/api.php')); }
您是否注意到方法中說起的 middleware, namespace 和 prefix ? 這是您能夠爲整個文件設置全局配置的地方,所以沒必要爲文件中的每一個路由組重複這些設置。
它主要用於 API 路由,由於它們的設置一般是相同的,以下所示:
protected function mapApiRoutes() { Route::group([ 'middleware' => ['api'], 'namespace' => $this->namespace, 'prefix' => 'api/v1', ], function ($router) { require base_path('routes/api.php'); }); }
上述方法將在全部 API URLs 的開頭加上 api/v1/ 前綴。
若是您有大量的路由,而且但願將它們分組到單獨的文件中,那麼您可使用上一節中提到的相同文件 – app/Providers/RouteServiceProvider.php。若是您仔細查看它的 map() 方法,您將在末尾看到註釋位置:
public function map() { $this->mapApiRoutes(); $this->mapWebRoutes(); // }
若是願意,您能夠將其解釋爲添加更多文件的「邀請」。所以,您能夠在此文件內建立另外一個方法,例如 mapAdminRoutes(),而後將其添加到 map() 方法, 您的文件將被自動註冊並加載。
可是,就我我的而言,我看不出這種方法有什麼優點,並且我也沒有常常看到這種作法。它會帶來更多的路由分離,但有時您會迷失在那些文件中,不肯定在哪裏查找特定的路由。
說到更大的路由並迷失在那裏,咱們有一個 Artisan 命令能夠幫助定位某個路由。
您可能知道 php artisan route:list 將展現項目中的全部路由
但您知道還有更多的過濾功能來找到您想要的東西嗎? 只需添加帶參數的 –method, 或 –name, 或 –path 。
經過 method 過濾 – GET, POST 等:
按名稱或 URL 部分過濾:
這就是我所能告訴的關於在大型項目中分組路由的所有內容。你還有其餘例子嗎?請在評論中分享。
原文連接: https://learnku.com/laravel/t...
討論請前往專業的 Laravel 開發者論壇: https://learnku.com/Laravel