thinkphp 8.0 的中间件链本质是职责链模式(cor)的工程化实现,而非标准 pipeline 类;其 think\middleware\pipeline 仅内部驱动中间件顺序执行,每个中间件作为具体处理器,通过 $next($request) 转发请求,链结构由配置静态构建,输入固化、不可动态拼装、输出由框架隐式接管。

ThinkPHP 8.0 并没有真正提供标准意义上的 Pipeline 类(如 Laravel 的 Illuminate\Pipeline\Pipeline),它所谓的“Pipeline”实际是中间件(middleware)的链式执行机制,本质属于职责链模式(Chain of Responsibility, CoR)的工程化落地,而非纯粹的管道模式(Pipeline Pattern)。
TP8 中间件链就是职责链
TP8 的 think\middleware\Pipeline 是框架内部驱动中间件顺序执行的核心类,但它不对外暴露为可自由实例化、任意传参的通用工具。整个请求生命周期中,所有注册的中间件自动组成一条职责链:
- 每个中间件是一个具体处理器(ConcreteHandler),实现
handle(Request $request, Closure $next)方法 - 调用
$next($request)即代表将控制权移交链中下一个处理器 —— 这正是 CoR 的核心语义:是否处理、是否转发,由当前节点自主决定 - 链的起点固定为框架入口,终点是控制器或响应生成器,链结构由配置(全局/路由级中间件)静态构建,符合 CoR “松耦合+开闭原则”的特征
和经典职责链的区别与限制
TP8 的职责链实现更偏向“框架约束型”,而非通用设计模式样板:
-
输入固化:所有中间件只接收
think\Request实例,无法像标准 CoR 那样灵活传递任意业务对象(如订单、用户凭证等) - 不可动态拼装:中间件必须在应用启动时注册到容器或路由定义中,不能在运行时临时 new Pipeline().send($data).through([...]).then(...) 构建新链
-
输出隐式接管:若中间件返回
think\Response实例,框架会立即中断链并返回;否则继续调用$next—— 这种“提前终止”逻辑由框架统一约定,开发者无需手动管理 successor 引用
如何写出符合 CoR 思想的 TP8 中间件
虽受框架约束,仍可通过合理设计体现职责链精髓:
- 每个中间件专注单一职责(鉴权 → 日志 → 参数校验 → 防刷 → 业务前置),不越界处理其他环节逻辑
- 拒绝处理时明确调用
return $next($request);能处理时直接返回响应(如 401、422),避免冗余传递 - 需要跨中间件共享数据时,使用
$request->withAttribute(),而非全局变量或静态属性,保持节点间低耦合 - 复杂流程可拆分为多个轻量中间件,利用框架的中间件分组与排序能力组织链路优先级
别把 TP8 当成 Laravel Pipeline 用
常见误区包括:
- 试图在控制器里 new Pipeline() 或调用不存在的
pipe()函数 - 期望把一个订单对象 push 进中间件链做业务编排
- 模仿 Laravel 的 then() 自定义终态,而 TP8 中间件返回值会被自动转为响应,无法自由接管最终输出
真正需要 Pipeline 风格的业务编排(如订单创建流水线、审核多级校验),应独立封装服务类 + 手动串联 Handler,而非强依赖 TP8 中间件机制。











