hyperf中间件执行顺序由注册数组索引从左到右决定,响应阶段逆序;优先级为单路由>路由组>全局;典型顺序为traceid→cors→解密/解析→鉴权→限流→日志。

Hyperf 中间件链的顺序直接决定请求处理流程,高频场景下(如鉴权、日志、限流)必须精准控制执行次序。核心原则是:越通用、越前置的中间件越早注册;业务强相关的放后;有依赖关系的需明确先后。
一、中间件注册顺序决定执行顺序
Hyperf 的中间件按 数组索引顺序 从左到右执行,响应阶段则逆序返回。例如:
'middleware' => [
\App\Middleware\TraceIdMiddleware::class, // ① 最先执行(请求阶段)
\App\Middleware\AuthMiddleware::class, // ② 次之
\App\Middleware\RateLimitMiddleware::class, // ③ 再次
\App\Middleware\LoggingMiddleware::class, // ④ 最后执行请求阶段
],
当响应返回时,LoggingMiddleware 先结束,TraceIdMiddleware 最后收尾(如清理上下文)。
二、全局中间件 vs 路由组中间件 vs 单路由中间件
优先级从高到低:单路由 > 路由组 > 全局。同级中间件按注册顺序叠加。
-
全局中间件:在
config/autoload/middlewares.php中配置'http'键,适用于所有 HTTP 请求 -
路由组中间件:用
->middleware([...])链式调用,仅作用于该组内所有路由 -
单路由中间件:在
GET/POST(...)->middleware([...])中指定,粒度最细,可覆盖组级配置
示例:
Router::addGroup('/api', function () {
Router::get('/user', [\App\Controller\UserController::class, 'index'])
->middleware([\App\Middleware\PermissionMiddleware::class]); // 仅此路由生效
}, [\App\Middleware\AuthMiddleware::class]); // 整个 /api 组都带 Auth
三、高频中间件典型顺序建议(含依赖说明)
以下为生产环境常见组合,兼顾性能与逻辑安全:
- TraceId / Context 初始化:必须最早,为后续中间件提供唯一请求标识和协程上下文支持
- 跨域(CORS):早于鉴权,避免预检失败被拦截
- 请求解密 / Body 解析:在 Auth 前完成,确保能读取 token 或签名字段
- 鉴权(Auth) & 权限(Permission):紧接解析之后,失败立即中断,不进业务层
- 限流(Rate Limit):建议放在鉴权后——区分游客/登录用户配额,也避免无效请求消耗令牌
- 日志记录 / 监控上报:靠后但要在业务控制器前(记录入参)和后(记录耗时、结果),通常用「前后包裹」方式实现
四、调试与验证中间件执行顺序
快速确认实际执行流:
- 在各中间件
process()开头加logger()->info('→ '.$this::class);,响应阶段加logger()->info('← '.$this::class); - 使用
php bin/hyperf.php route:list查看每条路由绑定的中间件列表(含继承关系) - 对关键中间件加
microtime(true)打点,分析各环节耗时分布 - 注意:中间件内抛出异常会跳过后续中间件(包括响应阶段),需配合
try/catch或异常处理器统一兜底
不复杂但容易忽略。









