文章转发自专业的Laravel开发者社区,原始链接:
https://
learnku.com/laravel/t/9
443/laravel-routing-optimizes-small-skill-sharing
当你作为一个初学者投身于 Laravel 的时候,Laravel 的路由器给你提供了一个很棒的优雅的 API。下面我要介绍的也不是什么隐藏的或者新的知识,它仅仅是在你学习 Laravel 的时候可能给你提供一些帮助的小技巧。
路由的 文档 非常不错,并且下文的技巧还会补充和拼凑一部分,这些部分将会帮助你快速掌握如何在 Laravel 项目中使用路由。
自定义命名空间
正如文档所言,如果你想在一个路由组里使用类似
AppHttpControllersAdmin
的命名空间,那么你可以使用 Laravel 5.4 里面介绍的 流式路由 API:
Route::namespace('Admin')->group(function () {
// "AppHttpControllersAdmin" 命名空间下的控制器
});
这正是每一个 Laravel 项目都会使用到的
RouteServiceProvider
技术:
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
由于
routes/web.php
文件拥有一个命名空间,所以
Admin
命名空间使用了相对路径。
要在
AppHttpControllersAdmin
命名空间下创建一个控制器,你可以在控制台运行下面这条命令:
php artisan make:controller -r Admin/UsersController
就跟之前的例子一样,这条命令在
routes/web.php
文件里面定义的路由类似这样:
Route::namespace('Admin')
->prefix('admin')
->group(function () {
Route::resource('users', 'UsersController');
});
路由宏
路由器是可以宏定义的,这意味着如果你想通过一个包提供一组路由,或者复用一组路由定义,那么你可以在服务提供者里面定义一个宏。
举个栗子,如果你有个商城的软件包,里面包含了很多购物路由,你想允许用户重写或者自定义一部分路由,那你可以这样做:
// 在服务提供者的 boot() 方法内
public function boot()
{
Route::macro('shopRoutes', function ($prefix) {
Route::group([
'prefix' => $prefix,
'middleware' => ['shopping'],
], function () {
Route::get('products/{product}', 'ProductsController@show');
// ...
});
});
}
接下来,用户就可以在一个新的 Laravel 项目的
routes/web.php
文件中调用刚刚那个宏了:
collect(config('languages'))->each(function ($language) {
Route::shopRoutes($language);
});
或者选择下面这种实现方式:
Route::macro('shopRoutes', function ($languages) {
Route::group([
'prefix' => '/{language}',
'middleware' => ['shopping'],
'where' => ['language' => implode('|', $languages)],
], function () {
Route::get('products/{product}', 'ProductsController@show');
// ...
});
});
宏的例子很抽象,但是你能明白其中的用意。我建议仅当路由宏能对你的项目有所帮助的时候才使用它。你会知道什么时候应该这么做的!
调试路由
在一个 Laravel 应用程序中,
web.php
文件(以及
api.php
文件)是程序能够响应的路由的自文档文件,我很欣赏这点。由于我更看重这个文件的文档这方面,所以我更偏向于一个个的定义路由而不是使用资源路由。
如果你发现自己想要找某一个路由或者调试所有可能定义的路由,
artisan route:list
这个命令会很有用:
artisan route:list
+--------+----------+----------+------+---------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+----------+------+---------+--------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | api/user | | Closure | api,auth:api |
+--------+----------+----------+------+---------+--------------+
route:list
这条命令对查看路由名称及其附加的中间件很有帮助。 这也引出了我下面要介绍的技巧:命名路由。
Named Group Routes
A common convention in Laravel is naming routes, which allows you to easily reference the
name
of the route and avoid hard-coding the root-relative URI in your templates. In some applications hard-coding the URI is fine, in other cases, the named routes allow the following:
{{ route('admin.users.show', ['user' => $user]) }}
{{-- /admin/users/2 --}}
When you are defining a group of routes, for example, our admin example, you can also prefix the name of the route on the group:
Route::namespace('Admin')
->prefix('admin')
->name('admin.')
->group(function () {
Route::resource('users', 'UsersController');
});
The above prefixed name would generate route names like the following for the
users
resource controller:
- admin.users.index
- admin.users.store
- admin.users.create
- admin.users.show
- admin.users.update
- admin.users.destroy
- admin.users.edit
Learn More
Read through the entire routing documentation and the resource controllers section of the controllers documentation. I reference the resource controllers section to try and ensure that most of my routes represent a REST verb and for route naming conventions.