Maison  >  Article  >  cadre php  >  Comment Laravel effectue-t-il le regroupement de routage ? Partage de 6 technologies d'organisation du routage

Comment Laravel effectue-t-il le regroupement de routage ? Partage de 6 technologies d'organisation du routage

青灯夜游
青灯夜游avant
2022-10-11 19:58:042002parcourir

Comment Laravel effectue-t-il le regroupement de routage ? Partage de 6 technologies d'organisation du routage

Le routage Laravel est une fonctionnalité que les développeurs apprennent dès le début. Mais à mesure que leur projet grandissait, il devenait de plus en plus difficile de gérer les fichiers de routage croissants, nécessitant souvent de les faire défiler pour trouver la bonne instruction Route::get(). Heureusement, il existe quelques techniques pour rendre les fichiers de routes plus courts et plus lisibles. Examinons différentes manières de regrouper les routes et leurs paramètres. 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

Nous ne parlerons pas seulement du bon vieux Route::group(), c'est le niveau débutant. Creusons un peu plus profondément.

Groupe 1. Route::resource et Route::apiResource

Commençons par l'éléphant dans la pièce : cela pourrait être le regroupement le plus couramment utilisé. Si vous disposez d'un ensemble typique d'opérations CRUD autour d'un modèle, vous devez les regrouper en contrôleurs de ressources🎜🎜Ce type de contrôleur contient jusqu'à 7 méthodes (mais probablement moins) : 🎜
  • index()
  • create()
  • store()
  • show()
  • edit()
  • update()
  • destroy()
🎜Donc, si votre ensemble d'itinéraires correspond à ces méthodes, veuillez ne pas le faire utilisez : 🎜🎜
$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'));
});
🎜🎜… Vous ne pouvez avoir qu'une seule ligne : 🎜🎜
Route::get('/', function () {
    return view('welcome');
});

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

require __DIR__.'/auth.php';
🎜🎜 Si vous utilisez un projet API, vous n'avez pas besoin de formulaire visuel pour créer/modifier, vous pouvez donc utiliser apiResource() couvre 5 syntaxes différentes sur 7 méthodes : 🎜🎜<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>🎜🎜 De plus, je vous recommande d'envisager des contrôleurs de ressources même si vous disposez de 2 à 4 méthodes au lieu des 7 complètes. Tout simplement parce qu'il maintient les conventions de dénomination standard - pour les URL, les méthodes et les noms de routes. Par exemple, dans ce cas, vous n'avez pas besoin de fournir le nom manuellement : 🎜🎜<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>Groupe 2. Groupes de sous-itinéraires imbriqués</strong> h2> 🎜Bien sûr, tout le monde connaît les <a href="https://learnku.com/docs/laravel/9.x/routing#route-groups">groupes de routage</a> généraux. Mais pour des projets plus complexes, un seul niveau de regroupement peut ne pas suffire. 🎜🎜Exemple pratique : vous souhaitez que les routes d'autorisation soient regroupées avec le middleware <code>auth, mais en interne, vous devez séparer davantage de sous-groupes, tels que les administrateurs et les utilisateurs simples. 🎜🎜rrreee🎜

Regroupement 3. Regroupez les middlewares en double

🎜Si vous avez beaucoup de middlewares, placez-en quelques-uns dans les groupes de routage. Que faire si cela arrive à plusieurs reprises ? 🎜🎜rrreee🎜🎜Comme vous pouvez le constater, il existe 5 middlewares, dont 4 sont des doublons. Par conséquent, dans le fichier app/Http/Kernel.php, nous pouvons déplacer ces 4 éléments vers un groupe de middleware distinct : 🎜🎜rrreee🎜🎜Nommez donc notre groupe de middleware comme check_user , maintenant nous pouvons abréger l'itinéraire : 🎜🎜rrreee🎜

Groupe 4. Même nom de contrôleur, espace de noms différent h2>🎜C'est très courant, par exemple, pour que HomeController soit défini pour différents rôles d'utilisateur, tels que Admin/HomeController et User/HomeController. Si vous utilisez le chemin complet dans le routage, cela ressemble à ceci : 🎜🎜rrreee🎜🎜Le chemin complet est utilisé pour chaque contrôleur Cela semble redondant, non ? C'est pourquoi de nombreux développeurs préfèrent avoir juste HomeController::class dans la liste des routes et ajouter quelque chose comme ceci en haut : 🎜🎜rrreee🎜🎜 Mais le problème ici est que nous avons le même nom de classe de contrôleur. ! Donc, ça ne marche pas : 🎜🎜rrreee🎜🎜Lequel est le contrôleur du "backend admin" ? Bon, une façon est de changer le nom et d'attribuer un alias à l'un d'entre eux : 🎜🎜rrreee🎜🎜 Mais, personnellement, changer le nom de la classe supérieure me déroute, je préfère une autre façon : pour le contrôleur Ajouter un espace de noms () dans le sous-dossier : 🎜🎜rrreee🎜

Groupe 5. Fichiers de routage séparés

🎜Si vous sentez routes/web.php ou <code>routes/api.php est trop volumineux. Vous pouvez mettre certaines routes dans un fichier séparé. Vous pouvez le nommer comme vous le souhaitez, par exemple routes /admin.phpcode>. 🎜🎜Pour charger ce fichier, il y a deux manières : je l'appelle la "voie Laravel" et la "voie PHP". 🎜🎜Si vous souhaitez suivre la structure de la façon dont Laravel construit ses fichiers de route par défaut, consultez <strong>app/Providers/RouteServiceProvider.php</strong> : 🎜🎜rrreee🎜🎜<code>routes/api.php code> et <code>routes/web.php sont tous ici, mais les paramètres sont légèrement différents. Il vous suffit donc d'ajouter le fichier admin ici : 🎜🎜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视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer