ThinkPHP中间件执行顺序由注册时机和作用层级共同决定,非文件名、类名或配置数组直读顺序;全局→路由→控制器三层固定层级,同层才按数组索引或链式调用序执行。

ThinkPHP中间件执行顺序不看文件名、不看类名,也不完全按config/middleware.php里数组的书写顺序“直读直用”,而是由注册时机和作用层级共同决定。理解这两点,才能真正控住顺序,避免Auth没拦住请求、日志漏打、CSRF校验失效等典型问题。
全局中间件:顺序由数组索引决定
全局中间件(即配置在config/middleware.php中middleware键下的数组)按数组下标从0开始依次执行——这是唯一影响其内部顺序的因素。
- 数组第一个元素最先执行,最后一个最晚(在全局层内)
- 别名映射(如
'auth' => \app\middleware\Auth::class)不影响顺序,只影响写法简洁性 - TP6+ 已废弃
app/middleware.php,统一以config/middleware.php为准;若两者并存,仅后者生效
路由中间件:注册位置决定插入时机
通过Route::get(...)->middleware([...])或分组Route::group(...)->middleware([...])添加的中间件,默认采用前置插入策略:它会插在整个全局中间件链之后、控制器中间件之前,并且多个路由级中间件之间,按->middleware()调用的先后顺序执行。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 同一个路由上多次调用
->middleware(),越早写的越先执行(请求阶段) - 不同路由定义中的中间件互不影响,各自独立嵌套
- 禁用
@middleware注解——v6+ 默认关闭,IDE不识别、调试困难、热更新不触发重载
层级优先于同层顺序:跨层级时顺序不可颠倒
ThinkPHP天然划分三层执行流:全局 → 路由 → 控制器。哪怕你在config/middleware.php里把某个权限中间件写在第一位,它也永远排在所有路由中间件之后;同样,控制器级$middleware属性声明的中间件,一定在路由中间件执行完才启动。
立即学习“PHP免费学习笔记(深入)”;
- 层级关系固定,无法通过调整数组顺序打破
- 只有同一层级内的多个中间件,才按注册顺序(数组索引或链式调用序)排序
- 例如:
ForceHttpsMiddleware必须放全局第一,因为它不依赖任何请求解析结果;而ParseJsonBody必须在AuthMiddleware之前,否则$request->post()为空
安全中间件链要按依赖关系排布
校验类中间件不是并列关系,而是存在明确数据依赖链。错位会导致参数丢失、校验跳过甚至静默失败。
-
ForceHttpsMiddleware→ 最前,无依赖,强制协议升级 -
ValidatePostSize→ 紧随其后,防止大文件绕过后续限制 -
ParseJsonBody/VerifyCsrfToken→ 必须在鉴权前,确保能读取原始body和token -
AuthMiddleware+CheckPermission→ 连续靠前,中间不插入语言包、日志等非校验中间件 -
Logger→ 放靠后,需完整上下文(如控制器名、动作名、响应状态)


















