这里主要分析resolve()理解think中间件的执行顺序
protected function resolve()
{
return function (Request $request) {
$middleware = array_shift($this->queue);
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;
};
}这里的resolve()方法将返回一个待调用的中间件闭包多个中间件的执行顺序主要执行逻辑在
$response = call_user_func_array($call, [$request, $this->resolve(), $param]);第二个参数$this->resolve()将获取下个待调用的中间件闭包这样将注册的中间件队列queue中的所有中间件组织为一个待调用中间件闭包洋葱式结构
执行的时候 则从第一层中间件开始执行,然后调用下层中间件,然后调用下下个中间,直到最后一层中间件
接着从最后一层中间件开始返回到上一层中间件,然后再返回到上上层中间件,
最后返回到第一层中间件
---->before ----> before ----> before --------->
|
Middleware1 Middleware2 Middleware3 Controller:action
|
<----after <---- after <---- after <--------- 下面写个简单的测试例子1 生成中间件m1 m2 m3
php think make:middleware m1
php think make:middleware m2
php think make:middleware m32 中间件中添加输出信息;m1 中间件
<?php
namespace app\http\middleware;
class m1
{
public function handle($request, \Closure $next)
{
$class = __CLASS__;
// 前置执行逻辑
echo "我在".$class."前置行为中<br>";
$response = $next($request);
//后置执行 后置执行逻辑
echo "我在".$class."后置行为中<br>";
return $response;
}
};m2中间件
<?php
namespace app\http\middleware;
class m2
{
public function handle($request, \Closure $next)
{
$class = __CLASS__;
// 前置执行逻辑
echo "我在".$class."前置行为中<br>";
$response = $next($request);
//后置执行 后置执行逻辑
echo "我在".$class."后置行为中<br>";
return $response;
}
};m3中间件
<?php
namespace app\http\middleware;
class m3
{
public function handle($request, \Closure $next)
{
$class = __CLASS__;
// 前置执行逻辑
echo "我在".$class."前置行为中<br>";
$response = $next($request);
//后置执行 后置执行逻辑
echo "我在".$class."后置行为中<br>";
return $response;
}
};index控制器
<?php
namespace app\index\controller;
class Index
{
public function index()
{
echo "我在控制器".__CLASS__."的方法".__METHOD__."方法中<br>";
}
public function hello($name = 'ThinkPHP5')
{
return 'hello,' . $name;
}
}3 添加中间件;app\middleware.php
<?php
return [
'm1',
'm2',
'm3',
];3 执行结果我在app\http\middleware\m1前置行为中
我在app\http\middleware\m2前置行为中
我在app\http\middleware\m3前置行为中
我在控制器app\index\controller\Index的方法app\index\controller\Index::index中
我在app\http\middleware\m3后置行为中
我在app\http\middleware\m2后置行为中
我在app\http\middleware\m1后置行为中中间件的用途可以用来在控制器的操作执行前的前置行为中进行相关的权限检测Auth
如果不符合权限,则直接return返回上层,不执行控制器的的操作
可以用来在控制器的操作执行完的后置行为中进行相关的逻辑回调
具体就是将上面中间件的echo语句换成对应的处理流程。
think中间的详细实现具体见 https://www.kancloud.cn/zmwtp/thinkphp/577076
最佳答案