Laravel中间件总结

2020-07-07 15:42:39 查看 884 回复 0

Laravel有三种中间件:$middleware,$routeMiddleware,$middlewareGroups。

$middleware 属性:这个属性称为全局中间件,为什么说是全局中间件呢?因为你的每一次请求,这里面的每个中间件都会执行。

$routeMiddleware 属性:这个属性称为路由中间件,为什么说是路由中间件呢?因为定义在该属性内的中间件,只能在定义路由时候引用。

假设这是我们定义的路由中间件:
protected $routeMiddleware = [
    ...
    'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
];

如果我们要使用 \Illuminate\Auth\Middleware\Authenticate::class 这个中间件该怎么做呢?

Route::get('hello/laravel-china','XXController@index')->middleware('auth');

我们定义路由时候调用了 middleware 方法,参数值是 auth, 这样访问这个路由的时候,就会执行该中间件。明白了吧!很简单的。

$middlewareGroups 属性:这个属性称为中间件组,为什么说是中间件组呢?我们之前说了路由中间件,是不是感觉这样添加路由中间件很麻烦,比如我们执行 10 个中间件,是不是就要在定义路由时候添加 10 个呢?有了中间件组就不用这么麻烦了。

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        ...
    ],
    'api' => [
        ...
    ],
];

好了,上面的例子就是定义中间件组的格式,比如我们看 web 这个键值,它对应为一个数组,该数组有多个中间件组成。当我们定义好后,该怎么使用呢?

我们在声明路由的时候,这样调用就可以了。

Route::group(['middleware' => 'web'],function($route){
    $route->get('hello/world',function(){});
    $route->get('hello/php',function(){});
    // 这样在访问这个这些路由的时候,就会执行中间件组 web 所对应的中间件,方便多了,批量式的。
});

总结:

$middleware:全局中间件,要对所有的请求要做一些处理的时候,就适合定义在该属性内。(比如统计请求次数这些)

$middlewareGroups:中间件组,比如我们项目有 api 请求和 web 的请求的时候,就要把两种类型的请求中间件分离开来,这时候就需要我们中间件组啦。

$routeMiddleware:路由中间件,有些个别的请求,我们需要执行特别的中间件时,就适合定义在这属性里面。


附加:

laravel构造函数和中间件执行顺序问题。

   BaseController.php 放置公共的中间件  
        class BaseController  
        {  
            public function __construct(){  
                $this->middleware('login');    
            }  
        }  
      
        IndexController.php 继承 BaseController  
        class IndexController extends BaseController  
        {  
            $user;  // 存储登录用户实例  
            public function __construct(){  
                parent::__constuct();  
                $this->user = Auth::user();  
            }  
        }  

构造函数和中间件的执行顺序有问题:  

1.先执行构造函数  

 2.再调用中间件 
官方论坛有说:https://laravel-china.org/topics/3218/laravel53-middleware-and-controller-construction-method-execution-sequence-problem

解决方法:  

都只能在route.php 中了  

1>要么使用 route::get()->middle('login')  

 2>要么使用 route::get(['middleware' => 'login', xxx])  

最好的方法,应该是使用路由组 route::group(['middleware' => 'login']) 

有一个例外的使用,就是输出跨域请求头的时候可以这样使用。数据处理完毕最后添加跨域请求头!