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即可。