thinkphp6版本的中间件注册机制是在实例化控制器后执行的,而实例化是由容器Container进行的,源码如下:
public function invokeClass(string $class, array $vars = [])
{
try {
$reflect = new ReflectionClass($class);
} catch (ReflectionException $e) {
throw new ClassNotFoundException('class not exists: ' . $class, $class, $e);
}
if ($reflect->hasMethod('__make')) {
$method = $reflect->getMethod('__make');
if ($method->isPublic() && $method->isStatic()) {
$args = $this->bindParams($method, $vars);
$object = $method->invokeArgs(null, $args);
$this->invokeAfter($class, $object);
return $object;
}
}
$constructor = $reflect->getConstructor();
$args = $constructor ? $this->bindParams($constructor, $vars) : [];
$object = $reflect->newInstanceArgs($args);
$this->invokeAfter($class, $object);
return $object;
}
这里需要注意的是,当被实例化的控制器的__construct中定义了exit、die等退出方法时,会导致newInstanceArgs执行之后退出,导致排在其后的注册中间件操作不再被执行。
解决方案则是:
移除控制器的__construct中定义了exit、die等退出方法,更换为return即可。