Чтобы передать запрос глубже в приложение (позволив промежуточному программному обеспечению «пройти»), просто вызовите обратный вызов $next с $request. https://laravel.com/docs/5.4/middleware#defining-middleware< /а>сильный>
Когда Laravel обрабатывает запрос, он запускает все применимое промежуточное ПО в стеке. Промежуточное ПО можно настроить для запуска до и/или после метода маршрута/контроллера.
Чтобы сделать это, 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());
Pipeline
— это Illuminate\Routing\Pipeline
, который расширяет Illuminate\Pipeline\Pipeline
.
Метод then()
выше по существу:
->then(function ($request) {
$this->app->instance('request', $request);
return $this->router->dispatch($request);
})
Then означает, что мы начинаем с замыкания, которое принимает конечные результаты (вспомните, что замыкание еще не было вызвано).
Затем в методе 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);
});
};);
};);
};
Надеюсь это поможет!
person
Rwd
schedule
13.02.2017
$next
внутриhandle
состоит в том, чтобы делать определенные вещи, которые не должен делать самhandle
. В случаеValidatePostSize
next
отвечает за выполнение условной проверки. Проверка — Laravel (см. раздел Комплексная условная проверка). - person Rendy Eko Prastiyo   schedule 13.02.2017