>PHP 프레임워크 >Laravel >Laravel은 라우팅 그룹화를 어떻게 수행합니까? 6가지 라우팅 조직 기술 공유

Laravel은 라우팅 그룹화를 어떻게 수행합니까? 6가지 라우팅 조직 기술 공유

青灯夜游
青灯夜游앞으로
2022-10-11 19:58:042123검색

Laravel은 라우팅 그룹화를 어떻게 수행합니까? 6가지 라우팅 조직 기술 공유

Laravel 라우팅은 개발자가 처음부터 배우는 기능입니다. 그러나 프로젝트가 성장함에 따라 늘어나는 라우팅 파일을 관리하기가 점점 더 어려워졌고 올바른 Route::get() 문을 찾기 위해 스크롤해야 하는 경우가 많았습니다. 다행히 경로 파일을 더 짧고 읽기 쉽게 만드는 몇 가지 기술이 있습니다. 경로와 해당 설정을 그룹화하는 다양한 방법을 살펴보겠습니다. 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

단순히 오래된 Route::group()에 대해서만 이야기하는 것이 아니라 초보자 수준입니다. 조금 더 자세히 살펴보겠습니다.

그룹 1. Route::resource 및 Route::apiResource

방에 있는 코끼리부터 시작해 보겠습니다. 가장 일반적으로 사용되는 그룹화. 모델에 대한 일반적인 CRUD 작업 세트가 있는 경우 이를 리소스 컨트롤러 / a>🎜🎜이 유형의 컨트롤러에는 최대 7개의 메서드가 포함되어 있습니다. > (그러나 아마도 더 적을 수도 있음): 🎜
  • index()
  • create()
  • store()
  • show()
  • edit()
  • update()
  • destroy()
🎜따라서 경로 세트가 이러한 메소드에 해당하는 경우, 하지 마십시오. 사용: 🎜🎜
$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'));
});
🎜🎜… 한 행만 가질 수 있습니다: 🎜🎜
Route::get('/', function () {
    return view('welcome');
});

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');

require __DIR__.'/auth.php';
🎜🎜 API 프로젝트를 사용하는 경우 생성/편집을 위한 시각적 형식이 필요하지 않으므로 apiResource()는 7가지 메소드 중 5가지 구문을 포함합니다. 🎜🎜<pre class="brush:php;toolbar:false;" style="max-height: none;">Route::get(&amp;#39;profile&amp;#39;, [ProfileController::class, &amp;#39;getProfile&amp;#39;]); Route::put(&amp;#39;profile&amp;#39;, [ProfileController::class, &amp;#39;updateProfile&amp;#39;]); Route::delete(&amp;#39;profile&amp;#39;, [ProfileController::class, &amp;#39;deleteProfile&amp;#39;]);</pre>🎜🎜 또한 전체 7개 메소드 대신 2~4개 메소드가 있더라도 리소스 컨트롤러를 고려하는 것이 좋습니다. URL, 메소드 및 경로 이름에 대한 표준 명명 규칙을 유지하기 때문입니다. 예를 들어, 이 경우 이름을 수동으로 제공할 필요가 없습니다: 🎜🎜<pre class="brush:php;toolbar:false;" style="max-height: none;">Route::controller(ProfileController::class)-&gt;group(function() { Route::get(&amp;#39;profile&amp;#39;, &amp;#39;getProfile&amp;#39;); Route::put(&amp;#39;profile&amp;#39;, &amp;#39;updateProfile&amp;#39;); Route::delete(&amp;#39;profile&amp;#39;, &amp;#39;deleteProfile&amp;#39;); });</pre>🎜<hr> <h2 id="8fdc83"> <strong>그룹 2. 중첩된 하위 경로 그룹</strong> h2> 🎜물론 일반적인 <a href="https://learnku.com/docs/laravel/9.x/routing#route-groups">라우팅 그룹</a>에 대해서는 누구나 알고 있습니다. 그러나 더 복잡한 프로젝트의 경우 한 가지 수준의 그룹화만으로는 충분하지 않을 수 있습니다. 🎜🎜실제 예: 인증 경로를 <code>auth 미들웨어로 그룹화하려고 하지만 내부적으로는 관리자 및 단순 사용자와 같은 더 많은 하위 그룹을 분리해야 합니다. 🎜🎜rrreee🎜

그룹화 3. 중복 미들웨어 그룹화

🎜미들웨어가 많은 경우 라우팅 그룹에 일부 포함 반복적으로 발생한다면? 🎜🎜rrreee🎜🎜보시다시피 5개의 미들웨어가 있고 그 중 4개는 중복입니다. 따라서 app/Http/Kernel.php 파일에서 이 4개를 별도의 미들웨어 그룹으로 이동할 수 있습니다. 🎜🎜rrreee🎜🎜미들웨어 그룹의 이름을 check_user로 지정하세요. , 이제 경로를 축약할 수 있습니다: 🎜🎜rrreee🎜

그룹 4. 동일한 이름 컨트롤러, 다른 네임스페이스 h2>🎜매우 일반적입니다. 예를 들어 Admin/HomeControllerUser/HomeController와 같은 다양한 사용자 역할에 대해 HomeController를 설정합니다. 라우팅에서 전체 경로를 사용하면 다음과 같습니다. 🎜🎜rrreee🎜🎜전체 경로는 각 컨트롤러에 사용됩니다. 중복되는 것 같죠? 이것이 바로 많은 개발자가 경로 목록에 HomeController::class만 두고 상단에 다음과 같은 것을 추가하는 것을 선호하는 이유입니다. 🎜🎜rrreee🎜🎜 하지만 여기서 문제는 컨트롤러 클래스 이름이 동일하다는 것입니다. ! 따라서 이것은 작동하지 않습니다. 🎜🎜rrreee🎜🎜 "관리자 백엔드"의 컨트롤러는 무엇입니까? 한 가지 방법은 이름을 변경하고 그 중 하나에 별칭을 할당하는 것입니다. 🎜🎜rrreee🎜🎜 하지만 개인적으로 최상위 클래스의 이름을 변경하면 혼란스러워서 다른 방법을 선호합니다. 컨트롤러의 경우 네임스페이스 추가() 하위 폴더에: 🎜🎜rrreee🎜

그룹 5. 별도의 라우팅 파일

🎜 Routes/web.php 또는 <code>routes/api.php가 너무 큽니다. 일부 경로를 별도의 파일에 넣을 수 있습니다(예: routes /admin.php). 코드>. 🎜🎜이 파일을 로드하는 방법에는 두 가지가 있습니다. 저는 "Laravel 방식"과 "PHP 방식"이라고 부릅니다. 🎜🎜Laravel이 기본 경로 파일을 구축하는 방법의 구조를 따르려면 <strong>app/Providers/RouteServiceProvider.php</strong>를 확인하세요. 🎜🎜rrreee🎜🎜<code>routes/api.php code> 및 routes/web.php는 모두 여기에 있지만 설정이 약간 다릅니다. 따라서 여기에 관리자 파일을 추가하기만 하면 됩니다: 🎜🎜rrreee🎜

如果你不想深入研究 服务提供者,还有一种更简单的方法 - 只需 include/require 您的路由文件到另一个文件中,就像你在 Laravel 框架之外的任何 PHP 文件。

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

routes/web.php:

Route::get(&#39;/&#39;, function () {
    return view(&#39;welcome&#39;);
});

Route::get(&#39;/dashboard&#39;, function () {
    return view(&#39;dashboard&#39;);
})->middleware([&#39;auth&#39;])->name(&#39;dashboard&#39;);

require __DIR__.&#39;/auth.php&#39;;

分组 6. Laravel 9 中的新功能: Route::controller ()

如果你的 Controller 中有一些方法,但它们不遵循标准的 Resource 结构,您仍然可以对它们进行分组,而无需为每个方法重复 Controller 名称。

取而代之的是:

Route::get(&#39;profile&#39;, [ProfileController::class, &#39;getProfile&#39;]);
Route::put(&#39;profile&#39;, [ProfileController::class, &#39;updateProfile&#39;]);
Route::delete(&#39;profile&#39;, [ProfileController::class, &#39;deleteProfile&#39;]);

您可以这样做:

Route::controller(ProfileController::class)->group(function() {
    Route::get(&#39;profile&#39;, &#39;getProfile&#39;);
    Route::put(&#39;profile&#39;, &#39;updateProfile&#39;);
    Route::delete(&#39;profile&#39;, &#39;deleteProfile&#39;);
});

此功能在 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으로 문의하시기 바랍니다. 삭제