TP5.1 迁移到 TP6 中间件适配的核心是修改 handle 方法签名增加$params 参数,并将配置文件中的闭包定义改为类名数组。此改动适用于所有自定义中间件,若忽略签名变化会导致中间件完全不被调用。
先说结论:必须修改方法签名并调整注册方式,否则中间件失效
- 先确认 handle 方法签名是否包含第三个参数$params
- 先处理 app/middleware.php 中的闭包定义改为类名
- 再验证请求链路中中间件日志是否输出
快速处理思路
直接修改中间件类的 handle 方法签名,并在配置文件中移除闭包写法。
// 旧写法 (TP5.1)
public function handle($request, Closure $next)
{
// ...
}
// 新写法 (TP6)
public function handle($request, Closure $next, $params = [])
{
// ...
}// app/middleware.php 配置
// 旧写法
return [
function($request, $next) { ... }
];
// 新写法
return [
'app\\middleware\\Auth'
];为什么会这样
TP6 中间件签名机制变更,强制要求第三个参数,缺少该参数会导致框架匹配失败并跳过中间件。同时 TP6 不再支持闭包定义中间件,必须传递类名数组以确保容器正确实例化。
分步处理
第一步:修改方法签名
打开所有自定义中间件文件,将 handle 方法签名改为 public function handle($request, Closure $next, $params = [])。注意$params 必须有默认值。
第二步:调整配置文件
检查 app/middleware.php,移除所有闭包定义,替换为完整的类名路径。确保命名空间正确,如 'app\\middleware\\CheckLogin'。
第三步:区分注册位置
全局中间件写在 app/middleware.php,路由级中间件需在路由定义中显式调用->middleware(Auth::class)。漏写路由级中间件会导致该路由不生效。
怎么验证是否生效
在中间件 handle 方法开头添加日志记录,如 file_put_contents('test.log', 'middleware hit')。发起请求后检查日志文件是否有新增内容。若请求正常但无日志,说明中间件未被调用。
常见坑
- 闭包定义:TP6 配置文件中写闭包会导致错误,必须改为类名。
- 类型声明:$next 必须声明为\Closure 类型,否则在严格模式下报致命错误。
- 注册位置:全局与路由级中间件注册位置不同,混淆会导致权限校验失效。
常见问题
为什么中间件没报错但不生效?
handle 方法签名缺少$params 参数,框架匹配失败直接跳过该中间件。
TP6 还能用闭包定义中间件吗?
不能,TP6 不再支持闭包定义中间件,必须传类名数组。
路由级中间件在哪里配置?
需在路由定义中显式调用->middleware(Auth::class),不能只写在全局配置。
参考来源
- ThinkPHP 项目代码重构与版本升级策略_如何最小化升级风险
- ThinkPHP 版本迭代中的 API 接口变动_后端版本接口兼容处理