Hyperf中路由参数必须通过$request->getAttribute(Dispatched::class)->params获取,不可用$request->input();推荐使用@Param注解自动注入并支持类型转换。

Hyperf 中路由参数(即路径中 {id}、{name:\w+} 这类占位符匹配到的值)不能靠 $request->input() 或查询字符串方式获取,必须从路由匹配结果中提取——这是初学者最容易卡住的地方。
用 $request->getAttribute(Dispatched::class) 拿到原始路由参数
Hyperf 在路由匹配完成后,会把解析出的参数存进 Dispatched 对象,并挂载到 $request 上。这是唯一可靠、且框架原生支持的方式。
-
Dispatched::class是关键入口,不是字符串字面量 - 参数实际存在
$dispatched->params数组里,键名就是路由定义里的占位符名(如id、name) - 该对象在中间件、控制器、甚至部分监听器中都可用,但必须确保请求已进入路由分发阶段(比如不能在全局启动脚本里用)
// 示例:GET /user/{id:\d+} → /user/123
$dispatched = $this->request->getAttribute(Dispatched::class);
$id = $dispatched->params['id'] ?? null; // string "123"
@Param 注解比手动取更安全,但要注意类型和位置
如果你用的是注解路由(如 #[GetMapping("/user/{id}")]),推荐直接用 @Param 注解注入,Hyperf 会在调用控制器方法前自动解析并做基础类型转换。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 参数名必须和路由占位符完全一致(大小写敏感),否则注入为
null - 支持类型提示:声明
int $id时,Hyperf 会尝试转成整型;但若路由没加正则约束(如{id:\d+}),传入非数字仍可能失败 - 不能在构造函数或静态方法中使用,仅限控制器实例方法的参数位置
use Hyperf\HttpServer\Annotation\Param;
#[GetMapping("/user/{id:\d+}")]
public function show(#[Param] int $id)
{
// $id 已是 int 类型,无需再 cast
}
别混用 $request->input() 和路由参数
很多人误以为 $request->input('id') 能拿到 /user/123 里的 123,其实不能——input() 只读查询参数(?id=123)和表单体,不处理路径段。
- 路径参数 ≠ 查询参数:前者是 URL 路径结构的一部分,后者是
?后面的键值对 - 如果同时有
/user/{id}/edit?name=foo,$id来自路由,$name才该用$request->input('name') - 强行用
input()去取路径参数,结果永远是null,且无任何报错提示
动态路由带可选段时,params 数组可能缺键
像 /user/{id:\d+}/[/{tab:\w+}] 这种带方括号的可选参数,匹配 /user/123 时 $dispatched->params 里根本不会有 tab 键,而不是值为 null。
- 判断是否存在要用
isset($dispatched->params['tab']),而不是empty()或三元运算 - 用
@Param注解时,可选参数需显式标注#[Param(default: 'default')],否则方法调用会因缺少参数而报错 - 这种“键可能不存在”的行为容易引发未定义索引 Notice,尤其在日志或调试输出里被忽略


















