Home>Article>PHP Framework> How does Laravel perform routing grouping? Sharing of 6 routing organization technologies
Laravel routing is a feature that developers learn from the beginning. But as their project grew, it became increasingly difficult to manage the growing routing files, often requiring scrolling to find the correctRoute::get()
statement. Fortunately, there are some techniques to make route files shorter and more readable, let's look at different ways to group routes and their settings.
We won't just talk about the plain oldRoute::group()
, that's beginner level. Let's dig a little deeper.
Let’s start with the elephant in the room: this is probably the most commonly used grouping . If you have a typical set of CRUD operations around a model, you should group them into aResource Controller
Such a controller containsup to 7 methods( but probably less):
So if your route set corresponds to these methods, don't use:
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');
… You may only have one row:
Route::resource('books', BookController::class);
If you use an API project, you don't need a visual form for create/edit, so you can Covering 5 different syntaxes in 7 methods usingapiResource()
:
Route::apiResource('books', BookController::class);
Also, I recommend you consider resource controllers even if you have 2- 4 methods instead of the full 7. Simply because it maintains standard naming conventions - for URLs, methods and route names. For example, in this case you don't need to provide the name manually:
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']);
Of course, everyone knows the generalrouting grouping. But for more complex projects, one level of grouping may not be enough.
Practical example: You want authorization routing to be grouped with theauth
middleware, but internally you need to separate more subgroups, such as admins and simple users.
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 }); });
If you have a lot of middleware, have some in routing groups What to do if it happens repeatedly?
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 () { // ... 管理员路由 });
As you can see, there are 5 middlewares, 4 of which are duplicates. Therefore, in theapp/Http/Kernel.php
file, we can move these 4 to a separate middleware group:
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' ], ];
So we The middleware group name ischeck_user
, now we can abbreviate the route:
Route::prefix('students')->middleware(['check_user', 'check.invoice.status'])->group(function () { // ... student routes }); Route::prefix('managers')->middleware(['check_user'])->group(function () { // ... manager routes });
It is very common, for example, to haveHomeController
set for different user roles, such asAdmin/HomeController
andUser/HomeController
. If you use the full path in routing, it looks like this:
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']); });
The full path is used for each controller. This seems redundant, right? That's why many developers prefer to include onlyHomeController::class
in the routes list and add something like this at the top:
use App\Http\Controllers\Admin\HomeController;
But here's the problem Yes we have the same controller class name! So, this doesn't work:
use App\Http\Controllers\Admin\HomeController; use App\Http\Controllers\User\HomeController;
Which one is the controller of the "admin backend"? Well, one way is to change the name and assign an alias to one of them:
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']); });
But, personally, changing the name of the top class confuses me, I prefer the other One way: add a namespace () to the subfolder of the controller:
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']); // ... 来自用户命名空间的其他控制器 });
If you feel thatroutes/web.php
orroutes/api.php
is too big, you can put some routes into a separate file, you can name it whatever you want , for exampleroutes/admin.php
.
To load this file, there are two methods: I call it the "Laravel method" and the "PHP method".
If you want to follow the structure of how Laravel builds its default route files, check outapp/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
androutes/web.php
are both here, but with slightly different settings. So you just need to add the admin file here:
$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';
如果你的 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视频教程】
The above is the detailed content of How does Laravel perform routing grouping? Sharing of 6 routing organization technologies. For more information, please follow other related articles on the PHP Chinese website!