Laravel 5中的中间件执行顺序

Sam*_*hen 18 php laravel laravel-5 laravel-middleware

Laravel 5文档描述了分配两种方式中间件:

  1. 将中间件分配给控制器的路由.
  2. 在控制器的构造函数中指定中间件.

但是,我意识到在控制器__construct()函数中编写的任何代码都将在中间件之前运行,即使在控制器函数的第一行声明了中间件__construct.

我在Laravel github存储库中找到了类似问题的错误报告.然而,合作者关闭了该问题,声明"这是预期的行为.".

我想知道,middleware应该是应用程序之外的"层",而__construct功能是应用程序的一部分.为什么__construct函数在中间件之前执行(假设它是在中间件之前)?为什么会这样?

Cur*_*ros 9

应用程序逻辑驻留在控制器的方法中.所以基本上应用程序存在于控制器的方法中,而不是整个控制器本身.

中间件在请求进入相应的控制器方法之前运行.因此,这总是在实际应用之外.除非所有中间件都在传递请求,否则不会执行任何控制器方法.

$this->middleware("My\Middleware");您在控制器构造函数中放入的语句,REGISTERS My\Middleware用于在请求进入应用程序之前进行检查.

如果您看到中间件的代码并且请求是否正在通过,那么我们使用该$next($request);语句将其发送到下一个中​​间件.这允许为单个请求执行多个中间件.现在,如果Laravel在$this->middleware(...);声明中运行中间件,Laravel可能无法知道下一次检查哪个中间件.

因此,Laravel通过首先注册所有中间件来解决这个问题,然后将请求逐个传递给所有中间件.

  • 这是一个有趣的案例,中间件相对于构造函数运行.任何全局中间件实际上似乎都在构造函数之前运行*,而任何本地中间件都在构造函数之后运行.这种不一致导致我过去的困惑和麻烦. (2认同)

Jef*_*ett 8

设置中间件优先级 App\Http\Kernel

例如,在这里我需要首先运行我的自定义身份验证中间件(在替代绑定之前),所以我将它移到堆栈上:

public function __construct(Application $app, Router $router)
{
    /**
     * Because we are using a custom authentication middleware,
     * we want to ensure it's executed early in the stack.
     */
    array_unshift($this->middlewarePriority, MyCustomApiAuthMiddleware::class);

    parent::__construct($app, $router);
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您需要显式控制,您可以覆盖整个优先级结构(不推荐,因为您必须在升级过程中密切注意以查看框架是否发生变化)。特定于这个问题的是SubstituteBindings处理路由模型绑定的类,因此请确保您的身份验证中间件在此之前的某个时间出现。

/**
 * The priority-sorted list of middleware.
 *
 * Forces the listed middleware to always be in the given order.
 *
 * @var array
 */
protected $middlewarePriority = [
    \App\Http\Middleware\MyCustomApiAuthMiddleware::class
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \Illuminate\Auth\Middleware\Authenticate::class,
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];
Run Code Online (Sandbox Code Playgroud)


Bdw*_*wey 5

涵盖该问题另一个用例的另一个答案

如果与中间件之间的顺序有关

您可以在App \ Kernel中更新$ middlewarePriority。