Tp5.2 定義中介軟體時的Closure $next怎麼理解
阿新 • • 發佈:2018-11-28
定義中介軟體的步驟
預設中介軟體存放位置
'default_namespace' => 'app\\http\\middleware\\',
建立一個 Check中介軟體
<?php namespace app\http\middleware; class Check { public function handle($request, \Closure $next) { if ($request->param('name') == 'think') { return redirect('index/think'); } return $next($request); } }
中介軟體的入口執行方法必須是handle方法,而且第一個引數是Request物件,第二個引數是一個閉包。
如何理解$next($request)
1. new App())->run() 中 執行到了中介軟體排程方法
$response = $this->middleware->dispatch($this->request);
2.在 think\Middleware.php 中可以看到dispatch 方法 呼叫了
call_user_func($this->resolve($type), $request);
第一個引數 callback 是被呼叫的回撥函式,其餘引數是回撥函式的引數。
3. resolve() 是一個回撥函式 其中執行了$middleware = array_shift($this->queue[$type]);刪除並得到佇列中的第一個元素 。下一步list($call, $param) = $middleware;
下面值關鍵的一步
$response = call_user_func_array(array('app\http\middleware\Check','handle'), [$request, $this->resolve(), $param]);
call_user_func_array ( callable $callback , array $param_arr )
把第一個引數作為回撥函式(callback)呼叫,把引數陣列作(param_arr)為回撥函式的的引數傳入。
這裡的$this->resolve() 對應的就是 handle($request, \Closure $next) 的 \Closure $next 這個引數。
tp5.2中resolve() 方法如下
protected function resolve(string $type = 'route')
{
return function (Request $request) use ($type) {
$middleware = array_shift($this->queue[$type]);
if (null === $middleware) {
throw new InvalidArgumentException('The queue was exhausted, with no response returned');
}
list($call, $param) = $middleware;
try {
$response = call_user_func_array($call, [$request, $this->resolve(), $param]);
} catch (HttpResponseException $exception) {
$response = $exception->getResponse();
}
if (!$response instanceof Response) {
throw new LogicException('The middleware must return Response instance');
}
return $response;
};
}