如何设置Laravel中间件执行顺序?

时间:2015-06-26 05:58:10

标签: php laravel laravel-5 laravel-middleware

Laravel 5 documentation介绍了两种分配中间件的方法:

  1. 将中间件分配给控制器的路径。
  2. 在控制器的构造函数中指定中间件。
  3. 但是,我意识到在控制器__construct()功能中编写的任何代码都将在中间件之前运行,即使在第一行声明了中间件控制器的__construct功能。

    我在Laravel github存储库中找到了类似问题的bug report。然而,合作者关闭了该问题,声明“这是预期的行为。”。

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

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

4 个答案:

答案 0 :(得分:9)

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

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

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

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

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

答案 1 :(得分:5)

另一个用于解决该问题的另一个用例的答案

如果它与中间件之间的顺序有关,那就是

  

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

答案 2 :(得分:2)

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

以前是:

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-in-laravel-5-3

答案 3 :(得分:1)

template <typename K, typename V> BSONCXX_INLINE typename std::enable_if< std::is_same<typename std::decay<K>::type, const char *>::value>::type append_(std::tuple<K, V>&& t) { _core->key_owned(std::forward<K>(std::get<0>(t))); impl::value_append(_core, std::forward<V>(std::get<1>(t))); } 中设置中间件优先级

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

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