更深请求传递到应用程序(允许中间件“通行证”),只需调用$下一回调与$请求。 https://laravel.com/docs/5.4/middleware#defining-middleware
当Laravel正在处理的请求它运行堆栈中的所有适用的中间件。中间件可以设置为在路由/控制器方法之前和/或之后运行。
为了能够做到这一点Laravel使用Illuminate\Pipeline\Pipeline
。本质上,它使用array_reduce
遍历中间件栈然后返回一个Closure
来执行中间件。美容这个来自使用array_reverse
允许下一个中间件执行要传递到前一个。
更详细地说明一点:
当Illuminate\Foundation\Http\[email protected]
被称为它建立了sendRequestThroughRouter
其中有以下的响应:
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
Pipeline
是Illuminate\Routing\Pipeline
延伸Illuminate\Pipeline\Pipeline
。
以上then()
方法基本上是:
->then(function ($request) {
$this->app->instance('request', $request);
return $this->router->dispatch($request);
})
那么意味着我们开始了与接受最终结果一个闭合(在这一点请记住,关闭将不会被调用)。
然后,在then()
方法中,发生如上所述的array_reduce
和array_reverse
部分。
这里是当then()
方法实际发生的一个简单的例子(假设你知道array_reduce
是如何工作的):
function then(Closure $destination)
{
$pipeline = array_reduce(
array_reverse($this->middlewares),
//Remember $nextClosure is going to be the closure returned
//from the previous iteration
function ($nextClosure, $middlewareClass) {
//This is the $next closure you see in your middleware
return function ($request) use ($nextClosure, $middlewareClass) {
//Resolve the middleware
$middleware = app($middlewareClass);
//Call the middleware
return $middleware->{$this->method}($request, $nextClosure);
};
},
//The finial closure that will be called that resolves the destination
function ($request) use ($destination) {
return $destination($request);
}
);
return $pipeline($this->request);
}
说我们有3个中间件:
[
One::class,
Two::class,
Three::class,
];
上面的变量$pipeline
基本上是:
function ($request) {
return app(One::class)->handle($request, function ($request) {
return app(Two::class)->handle($request, function ($request) {
return app(Three::class)->handle($request, function ($request) {
return $destination($request);
});
};);
};);
};
希望这会有所帮助!
查看代码? –
这是堆栈中的下一个中间件关闭。 –
@MagnusEriksson查看问题的描述。我知道它的方法暗示了它的封闭性。我想知道的是handle()方法如何转换为闭包$ next。 –