ThinkPHP6.0中间件统一通过handle方法+闭包链式调用实现,必须返回Response实例;用php think make:middleware AuthCheck生成标准中间件,类名与文件名严格匹配,注册需在app/middleware.php中返回数组,执行顺序不可逆,未调用$next将中断后续流程。

中间件在 ThinkPHP6.0 里不是“拦截器”概念,没有 beforeAction 或 afterAction 这类控制器级钩子;它统一走 handle 方法 + 闭包链式调用,所有逻辑必须返回 Response 实例——这点不满足就会报错或白屏。
如何生成并定义一个基础中间件
用命令行最稳妥,避免手写路径或命名空间出错:
php think make:middleware AuthCheck
生成的文件在 app/middleware/AuthCheck.php,结构固定:
-
handle方法是唯一入口,必须接收$request和$next两个参数 - 不能漏掉
use \Closure;,否则$next类型提示失效 - 返回值必须是
Response对象,return $next($request)是放行,return redirect(...)或return json(...)是终止 - 如果中间件要读取配置或模型,推荐通过构造函数注入,而不是在
handle里用app()或Db::—— 否则测试和复用困难
中间件参数怎么传:class + 字符串 vs 数组形式
路由注册时传参有两种写法,行为完全不同:
立即学习“PHP免费学习笔记(深入)”;
-
->middleware(\app\middleware\AuthCheck::class, 'admin'):第三个参数'admin'会作为handle的第三个参数传入,即public function handle($request, \Closure $next, $role) -
->middleware([\app\middleware\AuthCheck::class, 'admin']):这种写法只在全局/应用中间件配置(如middleware.php)中有效,在路由里会解析失败 - 别在
handle方法里尝试解构$request->param()来替代参数传递——参数是运行时绑定的,比请求数据更可控、可测试
为什么中间件没执行?检查这三处硬性条件
中间件不生效,90% 出在这几个位置:
-
app/middleware.php文件必须存在且返回数组,哪怕内容是空数组[];如果文件不存在,框架压根不会加载任何全局中间件 - 中间件类名和文件名必须严格匹配,
AuthCheck.php里必须是class AuthCheck,大小写敏感,PSR-4 自动加载才认得 - 注册位置错误:比如把路由中间件写在了
config/app.php里,而它只认middleware.php或路由定义本身;app.php里没有中间件相关配置项
end 方法能做什么、不能做什么
end 是请求响应已发出后的回调,典型用途是日志记录、资源清理:
- 可以读
$response->getCode()、$response->getContent()(但注意内容可能已被压缩或加密) - 绝对不能调用
echo、var_dump、header()或任何输出函数,否则触发headers already sent - 不能返回值,也不接受参数以外的任何东西;想传数据进
end,得靠$request->withAttribute()在handle阶段存,再在end里用$request->getAttribute()取
真正容易被忽略的是:中间件顺序不可逆,pipeline 执行是单向穿透的,一旦某个中间件没调用 $next($request),后续所有中间件和控制器就彻底收不到请求——调试时建议在每个 handle 开头加 trace('in '.__CLASS__),比 var_dump 更安全。



















