TP8中间件必须实现PSR-15接口并重写process方法,签名须为process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface,返回ResponseInterface实例;middleware.php仅支持::class常量数组,类名须完整且可反射。

中间件类必须实现 PSR-15 接口
是的,必须重写。TP8 的中间件不再继承 think\Middleware,也不再接受 $request 和 Closure 参数。旧写法会直接报错或静默失效。
关键变化在于签名和返回值:原 handle($request, \Closure $next) 必须改为 process(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Server\RequestHandlerInterface $handler): \Psr\Http\Message\ResponseInterface。
- 不改接口会导致容器无法识别该类为合法中间件,抛出
BindingResolutionException -
$handler不是闭包,调用方式是$handler->handle($request),不是$next($request) - 必须显式
return一个ResponseInterface实例,否则响应为空白页或 500
全局中间件配置文件仍叫 middleware.php,但内容不能有 use
app/middleware.php 文件名没变,但语义已不同:它现在只是返回类名数组的纯配置脚本,不支持任何 PHP 语法糖。
- ✅ 正确写法:
return [\app\middleware\Auth::class]; - ❌ 错误写法:
use app\middleware\Auth; return [Auth::class];——use在此文件中被完全忽略,类名解析失败 - ❌ 错误写法:
return ['app\middleware\Auth'];—— 缺少反斜杠,PHP 尝试在当前命名空间(空)下查找,报Class "app\middleware\Auth" not found
路由级中间件绑定语法不变,但类名必须完整且可反射
->middleware() 调用形式保留,但底层校验更严格:TP8 依赖 PHP 8 的反射 API 解析类型,类名若拼错、命名空间不匹配、或构造函数参数类型声明缺失,都会导致中间件实例化失败。
- 确保中间件类有明确的构造函数类型提示,例如:
public function __construct(private \think\App $app) { } - 避免使用 PHP 7 风格的无类型构造参数,如
function __construct($app),TP8 容器可能无法注入依赖 - 闭包方式仍可用,但必须带完整类型提示:
function (\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Server\RequestHandlerInterface $handler)
控制器级中间件注册方式未变,但执行时机更早
$this->middleware->add() 依然有效,但注意:TP8 中控制器初始化流程提前,initialize() 执行时请求上下文已就绪,中间件注册后立即参与当前请求管道。
- 不能再在
initialize()里动态判断是否添加中间件(比如根据 URL 参数),因为此时路由已解析完成,中间件链已固化 - 若需条件拦截,应在中间件自身
process()方法内做逻辑分支,而非在控制器里控制注册 - 资源路由(
Route::resource())不再自动继承控制器注解,必须显式调用->middleware()
复杂点在于中间件不再“只管逻辑”,它成了 PSR-15 管道中不可绕过的一环;一个字符的命名空间错误、一行多余的 use、或一个未声明的类型提示,都可能导致整个请求流中断且无明确报错。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











