25

Laravel 5 文档描述了两种分配Middleware的方法:

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

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

我在 Laravel github 存储库中发现了一个类似问题的错误报告。然而,一位合作者关闭了该问题,并指出“这是预期的行为。”。

我认为middleware应该是应用程序之外的“层”,而__construct功能是应用程序的一部分。

为什么__construct函数在中间件之前执行(假设它是在中间件运行之前声明的)?为什么这是预期的?

4

4 回答 4

16

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

如果它与中间件之间的顺序有关,它自己

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

于 2018-02-01T16:04:30.367 回答
10

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

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

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

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

所以,Laravel 解决了这个问题,首先注册所有的中间件,然后将请求一个一个地传递给所有的中间件。

于 2015-06-27T01:59:03.063 回答
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);
}

或者,如果您需要显式控制,您可以覆盖整个优先级结构(不推荐,因为您必须在升级期间密切注意以查看框架是否更改)。特定于这个问题的是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,
];
于 2019-04-28T02:42:39.747 回答
3

他们更新了middlewares,controller和控制器构造之间的执行顺序。

以前是:

1. The global middleware pipeline
2. The route middleware pipeline
3. The controller middleware pipeline

现在它的:

1. The global middleware pipeline
2. Controller's Construct
3. The route & controller middlewares

在此处阅读更多信息: https ://laracasts.com/discuss/channels/general-discussion/execution-order-in-controllers-constructor-whit-middleware https://laravel-news.com/controller-construct-session-changes -在-laravel-5-3

于 2019-01-23T03:56:12.787 回答