gpt4 book ai didi

php - 如何在另一个中间件中使用 'Clousre $next' 调用 Laravel 中间件的 handle() 方法?

转载 作者:行者123 更新时间:2023-12-04 14:38:09 24 4
gpt4 key购买 nike

这是 Laravel 的 ValidatePostSize 中的 handle() 方法:

public function handle($request, Closure $next)
{
$max = $this->getPostMaxSize();

if ($max > 0 && $request->server('CONTENT_LENGTH') > $max) {
throw new PostTooLargeException;
}

return $next($request);
}

现在,使用 $next($request) 为另一个中间件调用此方法。我的理解是 handle() 方法被转换为 $next。我想知道这是如何发生在引擎盖下的。

最佳答案

To pass the request deeper into the application (allowing the middleware to "pass"), simply call the $next callback with the $request. https://laravel.com/docs/5.4/middleware#defining-middleware



当 Laravel 处理请求时,它会运行堆栈中所有适用的中间件。中间件可以设置为在路由/ Controller 方法之前和/或之后运行。

为了能够做到这一点,Laravel 使用 Illuminate\Pipeline\Pipeline .本质上,它使用 array_reduce遍历中间件堆栈,然后返回 Closure执行该中间件。美妙之处在于使用 array_reverse允许将下一个中间件执行传递给前一个。

再详细说明一点:

Illuminate\Foundation\Http\Kernel@handle被称为它用 sendRequestThroughRouter 建立响应其中包含以下内容:
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
PipelineIlluminate\Routing\Pipeline扩展 Illuminate\Pipeline\Pipeline .
then()上面的方法本质上是:
->then(function ($request) {
$this->app->instance('request', $request);

return $this->router->dispatch($request);
})

那么意味着我们从一个接受最终结果的闭包开始(记住此时不会调用闭包)。

然后,在 then()方法, array_reducearray_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);

});
};);
};);
};

希望这可以帮助!

关于php - 如何在另一个中间件中使用 'Clousre $next' 调用 Laravel 中间件的 handle() 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42198982/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com