ThinkPHP6路由中间件传参唯一方式是middleware()方法第二个参数,它作为第三个参数传入handle()方法,签名必须为public function handle($request, \Closure $next, $param)。

路由中间件传参必须用 middleware() 方法的第二个参数
ThinkPHP6 不支持在中间件类构造函数里接收路由传入的参数,也不能靠 $request->param() 拿到路由定义时“想传”的那个值——它根本没走请求参数解析流程。真正能传参的唯一入口,就是 Route::rule() 或 Route::group() 调用后的 middleware() 方法的第二个参数。
这个参数会作为第三个参数传递给中间件的 handle() 方法,前提是你的中间件方法签名明确声明了它:
public function handle($request, \Closure $next, $param)
如果漏写第三个形参,TP6 会静默忽略传入的值,不会报错,但你也拿不到。
- 单个中间件传参:
Route::get('admin/user', 'admin/user')->middleware(\app\middleware\Auth::class, 'admin')→handle()第三个参数是字符串'admin' - 多个中间件统一传参:
->middleware([\app\middleware\Auth::class, \app\middleware\Log::class], 'admin')→ 两个中间件的handle()都会收到'admin' - 多个中间件各自传参:不支持。TP6 没有提供按中间件索引分别传不同值的语法
handle() 方法签名写错会导致参数丢失
这是最常踩的坑:很多人复制示例时只改了逻辑,却忘了补全方法参数。TP6 的中间件调用机制很严格——只有签名完全匹配(参数个数、类型提示可选但顺序不能错),第三个参数才会被注入。
立即学习“PHP免费学习笔记(深入)”;
下面这几种写法都会让 $param 变成 null 或直接报错:
-
public function handle($request, $next)—— 少了\Closure类型提示,部分版本会拒绝调用 -
public function handle($request, \Closure $next, $param = null)—— 默认值看似安全,实则破坏了框架的参数绑定逻辑 -
public function handle($request, \Closure $next, $param, $extra)—— 多了一个未定义的参数,框架无法匹配
正确写法只有一种:public function handle($request, \Closure $next, $param),且不能加默认值。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
路由群组传参和单条路由传参行为一致
Route::group() 传参不是“批量配置”,而是对组内每条子路由都做一次等价的 middleware(..., $param) 调用。所以它和单条路由传参没有本质区别,只是写法更紧凑:
Route::group('api', function () {
Route::get('user', 'api/user');
Route::get('order', 'api/order');
})->middleware(\app\middleware\Scope::class, 'api_v1');
等效于:
Route::get('api/user', 'api/user')->middleware(\app\middleware\Scope::class, 'api_v1');
Route::get('api/order', 'api/order')->middleware(\app\middleware\Scope::class, 'api_v1');
注意:群组前缀(如 'api')本身不会自动变成参数传给中间件,它只是 URL 路径前缀,跟中间件参数无关。
别试图在中间件里用 $request->hello = 'xxx' 代替传参
有人看到文档里有“通过赋值给 $request 传值到控制器”的例子,就误以为也能这么传进中间件。这是混淆了两个场景:
-
$request->xxx = 'val'是把数据挂载到请求对象上,供后续控制器或其它中间件读取,属于“下游传递” - 路由
middleware()的第二个参数,是“上游注入”,由框架在调用handle()前主动塞进去的原始值
如果你需要把路由传参再转发给控制器,得自己中转一下:
public function handle($request, \Closure $next, $scope) {
$request->scope = $scope; // 手动挂到 request 上
return $next($request);
}
然后控制器里才能用 request()->scope 拿到。但这和“路由怎么传参给中间件”是两件事,别混为一谈。


















