Execution Order of Middleware in Laravel 5

2019-02-03 04:04发布

问题:

The Laravel 5 documentation describes two ways of assigning Middleware:

  1. Assign middleware to the controller's route.
  2. Specify middleware within your controller's constructor.

However, I realised that any code written in the controllers __construct() function will run before the Middleware, even if the Middleware is declared on the first line of the controller's __construct function.

I found a bug report for a similar issue in the Laravel github repository. However a collaborator closed the issue stating "This is the expected behaviour.".

I am wondering that, middleware should be "layers" outside the application, while the __construct function is part of the application. Why the __construct function is executed before the middleware (given it is a before middleware)?and why this is expected?

回答1:

The application logic resides in the controller's methods. So basically application lives in the controller's methods, not in the whole controller itself.

Middleware runs BEFORE the request enters the respective controller method. And thus, this is always OUTSIDE the real application. No controller method is executed unless all the Middlewares are passing the request.

The $this->middleware("My\Middleware"); statements that you put in the controller constructor, REGISTERS the My\Middleware for checking before the request enters the application.

If you see the code of a middleware and if the request is passing, then we send it to the next middleware using the $next($request); statement. This allows multiple middlewares to be executed for a single request. Now, if Laravel run the middleware right at the $this->middleware(...); statement, Laravel would probably not be able to know which middleware should be next checked.

So, Laravel solves this by registering all the middlewares first, then passing the request through all the middlewares one by one.



回答2:

Another answer to cover another use case to that question

If it's related to the order between middleware it self

You can update the $middlewarePriority in your App\Kernel.



回答3:

They updated the order of execution between middlewares, controller and controller's construct.

Previously it was:

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

Now its:

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

Read more here: 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