首頁  >  文章  >  php框架  >  Laravel如何進行路由分組? 6 種路由組織技術分享

Laravel如何進行路由分組? 6 種路由組織技術分享

青灯夜游
青灯夜游轉載
2022-10-11 19:58:041998瀏覽

Laravel如何進行路由分組? 6 種路由組織技術分享

Laravel 路由是開發人員從一開始就學習的功能。但是隨著他們專案的成長,管理不斷增長的路由檔案變得越來越困難,經常需要滾動查找正確的 Route::get() 語句。幸運的是,有一些技術可以使路由檔案更短、更易讀,讓我們來看看以不同的方式將路由及其設定分組。

我們不會只談論一般簡單的 Route::group(),那是初學者等級。讓我們再深入一點。


分組1. Route::resource 和Route::apiResource

#讓我們從房間裡的大象開始:這可能是最常用的分組。如果您圍繞一個模型有一組典型的CRUD 操作,則應該將它們分組到資源控制器

#此類控制器包含多達7 種方法(但可能更少):

  • index()
  • create()
  • #store()
  • show()
  • #edit()
  • update()
  • destroy()

#因此,如果您的路由集對應於這些方法,請不要使用:

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​​ 項目,則不需要用於建立/ 編輯的視覺化表單,因此您可以使用apiResource() 的涵蓋7 種方法中的5 種不同語法:

Route::apiResource('books', BookController::class);

#此外,我建議您考慮資源控制器,即使您有2- 4 個方法,而不是完整的7 個。只是因為它保持標準命名約定 - 對於 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.  巢狀子路由群組

當然,一般的路由分組 大家都知道。但對於更複雜的項目,一級分組可能還不夠。

實際範例:您希望授權路由與 auth 中間件進行分組,但在內部您需要分隔更多子群組,例如管理員和簡單使用者。

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. 將重複的中間件分組

如果你有很多中間件,有些在路由組中重複出現怎麼辦?

Route::prefix('students')->middleware(['auth', 'check.role', 'check.user.status', 'check.invoice.status', 'locale'])->group(function () {
    // ... 学生路由
});

Route::prefix('managers')->middleware(['auth', 'check.role', 'check.user.status', 'locale'])->group(function () {
    // ... 管理员路由
});

如您所見,有 5 個中間件,其中 4 個是重複的。因此,在app/Http/Kernel.php 檔案裡,我們可以將這4 個移到單獨的中間件群組:

protected $middlewareGroups = [
    // 此组是 Laravel 默认中间件组
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    // 此组是 Laravel 默认中间件组
    'api' => [
        // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    // 这是我们新的中间件组
    'check_user' => [
        'auth',
        'check.role',
        'check.user.status',
        'locale'
    ],
];

所以將我們的中間件組命明為check_user,現在我們可以縮寫路由:

Route::prefix('students')->middleware(['check_user', 'check.invoice.status'])->group(function () {
    // ... student routes
});

Route::prefix('managers')->middleware(['check_user'])->group(function () {
    // ... manager routes
});

分組4. 同名控制器,不同命名空間

很常見的情況是,例如,為不同的使用者角色設定了HomeController,例如Admin/HomeControllerUser/HomeController。如果在路由中使用完整路徑,它看起來像這樣:

Route::prefix('admin')->middleware('is_admin')->group(function () {
    Route::get('home', [\App\Http\Controllers\Admin\HomeController::class, 'index']);
});

Route::prefix('user')->middleware('is_user')->group(function () {
    Route::get('home', [\App\Http\Controllers\User\HomeController::class, 'index']);
});

每個控制器都是用了完整的路徑這看上去很冗餘,對吧?這就是為什麼許多開發人員更喜歡在路由列表中只包含HomeController::class 並在頂部添加類似這樣的內容:

use App\Http\Controllers\Admin\HomeController;

但是這裡的問題是我們有相同的控制器類別名稱!所以,這行不通:

use App\Http\Controllers\Admin\HomeController;
use App\Http\Controllers\User\HomeController;

哪一個是「管理後台」的控制器?好吧,一種方法是更改​​名稱並為其中之一分配別名:

use App\Http\Controllers\Admin\HomeController as AdminHomeController;
use App\Http\Controllers\User\HomeController;

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('App\Http\Controllers\Admin')->middleware('is_admin')->group(function () {
    Route::get('home', [HomeController::class, 'index']);
    // ... Admin 命名空间中的其他控制器
});

Route::prefix('user')->namespace('App\Http\Controllers\User')->middleware('is_user')->group(function () {
    Route::get('home', [HomeController::class, 'index']);
    // ... 来自用户命名空间的其他控制器
});

#分組5.分離路由檔案

如果你覺得routes/web.phproutes/api.php 太大了,可以把一些路由放到一個單獨的檔案中,你可以為它任意命名,例如routes/admin.php

要載入該文件,有兩種方法:我稱之為 “Laravel 方式” 和 “PHP 方式” 。

如果你想遵循Laravel 建立其預設路由檔案的結構,請查看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.phproutes/web.php 都在這裡,但設定略有不同。因此,你只需要在此處新增 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 文件。

事实上,这是由 Taylor Otwell 完成的,只需将 routes/auth.php 文件直接放入 Laravel Breeze 路由

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 中有一些方法,但它们不遵循标准的 Resource 结构,您仍然可以对它们进行分组,而无需为每个方法重复 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 的最新小版本中可用。


就是这样,这些分组技术有望帮助你组织和维护的路由,无论你的项目发展到多大。

原文地址:https://laravel-news.com/laravel-route-organization-tips

译文地址:https://learnku.com/laravel/t/68476

【相关推荐:laravel视频教程

以上是Laravel如何進行路由分組? 6 種路由組織技術分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:learnku.com。如有侵權,請聯絡admin@php.cn刪除