HTTP路由实例教程(二)—— 路由命名和路由分组


1、路由命名——给路由起个名字

1.1 基本使用

我们使用as关键字来为路由命名:

  1. Route::get('/hello/laravelacademy',['as'=>'academy',function(){
  2. return 'Hello LaravelAcademy!';
  3. }]);

路由命名可以让我们在使用route函数生成指向该路由的URL或者生成跳转到该路由的重定向链接时更加方便:

  1. Route::get('/testNamedRoute',function(){
  2. return route('academy');
  3. });

我们在浏览器中访问http://laravel.app:8000/testNamedRoute时输出http://laravel.app:8000/hello/laravelacademy,然后我们修改上述闭包内代码:

  1. Route::get('/testNamedRoute',function(){
  2. return redirect()->route('academy');
  3. });

再次在浏览器中访问http://laravel.app:8000/testNamedRoute时会跳转到http://laravel.app:8000/hello/laravelacademy

我们甚至还可以在使用带参数的路由命名:

  1. Route::get('/hello/laravelacademy/{id}',['as'=>'academy',function($id){
  2. return 'Hello LaravelAcademy '.$id.'!';
  3. }]);

对应的测试路由定义如下:

  1. Route::get('/testNamedRoute',function(){
  2. return redirect()->route('academy',['id'=>1]);
  3. });

这样,当我们在浏览器中访问http://laravel.app:8000/testNamedRoute时会跳转到http://laravel.app:8000/hello/laravelacademy/1

1.2 路由分组时路由命名方式

再来看一个更复杂的例子,使用路由分组时如何定义路由命名?官网文档提供的例子如下:

  1. Route::group(['as' => 'admin::'], function () {
  2. Route::get('dashboard', ['as' => 'dashboard', function () {
  3. //
  4. }]);
  5. });

Route门面的group方法中使用一个as关键字来指定该路由群组中所有路由的公共前缀,然后再在里面每个路由中使用as关键字为该路由命名。

这样我们可以通过如下方式来生成该路由URL:

  1. Route::get('/testNamedRoute',function(){
  2. return route('admin::dashboard');
  3. });

2、路由分组

路由分组就是将一组拥有相同属性(中间件、命名空间、子域名、路由前缀等)的路由使用Route门面的group方法聚合起来。

2.1 中间件

首先我们在应用根目录下运行如下Artisan命令生成一个测试用的中间件TestMiddleware

  1. php artisan make:middleware TestMiddleware

这样会在/app/Http/Middleware目录下生成一个TestMiddleware.php文件,打开该文件编辑TestMiddleware类的handle方法如下:

  1. public function handle($request, Closure $next)
  2. {
  3. if($request->input('age')<18)
  4. return redirect()->route('refuse');
  5. return $next($request);
  6. }

我们在中间件中定义这段业务逻辑的目的是年龄18岁以下的未成年人不能访问。

然后我们打开/app/Http/Kernal.php文件,新增TestMiddlewareKernel$routeMiddleware属性:

  1. protected $routeMiddleware = [
  2. 'auth' => \App\Http\Middleware\Authenticate::class,
  3. 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
  4. 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
  5. 'test' => \App\Http\Middleware\TestMiddleware::class,
  6. ];

接下来我们在routes.php中定义路由如下:

  1. Route::group(['middleware'=>'test'],function(){
  2. Route::get('/write/laravelacademy',function(){
  3. //使用Test中间件
  4. });
  5. Route::get('/update/laravelacademy',function(){
  6. //使用Test中间件
  7. });
  8. });
  9.  
  10. Route::get('/age/refuse',['as'=>'refuse',function(){
  11. return "未成年人禁止入内!";
  12. }]);

这样当我们在浏览器中访问http://laravel.app:8000/write/laravelacademy?age=15或者http://laravel.app:8000/update/laravelacademy?age=15时就会跳转到http://laravel.app:8000/age/refuse,并显示:

  1. 未成年人禁止入内!

2.2 命名空间

默认情况下,routes.php中的定义的控制器位于App\Http\Controllers命名空间下,所以如果要指定命名空间,只需指定App\Http\Controllers之后的部分即可:

  1. Route::group(['namespace' => 'LaravelAcademy'], function(){
  2. // 控制器在 "App\Http\Controllers\LaravelAcademy" 命名空间下
  3.  
  4. Route::group(['namespace' => 'DOCS'], function()
  5. {
  6. // 控制器在 "App\Http\Controllers\LaravelAcademy\DOCS" 命名空间下
  7. });
  8. });

2.3 子域名

子域名可以通过domain关键字来设置:

  1. Route::group(['domain'=>'{service}.laravel.app'],function(){
  2. Route::get('/write/laravelacademy',function($service){
  3. return "Write FROM {$service}.laravel.app";
  4. });
  5. Route::get('/update/laravelacademy',function($service){
  6. return "Update FROM {$service}.laravel.app";
  7. });
  8. });

这样我们在浏览器中访问http://write.laravel.app:8000/write/laravelacademy,则输出

  1. Write FROM write.laravel.app

访问http://update.laravel.app:8000/write/laravelacademy时,则输出:

  1. Write FROM update.laravel.app

注意:要想让子域名解析生效,需要在hosts中绑定IP地址

2.4 路由前缀

如果路由群组中的所有路由包含统一前缀,则我们可以通过在group方法中设置prefix属性来指定该前缀:

  1. Route::group(['prefix'=>'laravelacademy'],function(){
  2. Route::get('write',function(){
  3. return "Write LaravelAcademy";
  4. });
  5. Route::get('update',function(){
  6. return "Update LaravelAcademy";
  7. });
  8. });

这样我们就可以通过http://laravel.app:8000/laravelacademy/write或者http://laravel.app:8000/laravelacademy/update来访问对应的操作。

我们甚至还可以在路由前缀中指定参数:

  1. Route::group(['prefix'=>'laravelacademy/{version}'],function(){
  2. Route::get('write',function($version){
  3. return "Write LaravelAcademy {$version}";
  4. });
  5. Route::get('update',function($version){
  6. return "Update LaravelAcademy {$version}";
  7. });
  8. });

这样我们在浏览器中访问http://laravel.app:8000/laravelacademy/5.1/write,则对应会输出:

  1. Write LaravelAcademy 5.1