Hyperf中路由与控制器对应关系由注解扫描和路由注册两阶段决定:需确保控制器类被AnnotationScanner扫描到(路径在config/autoload/annotations.php的scan.paths中、命名空间与文件路径严格匹配、#[Controller]写在类上),且prefix与method path拼接时避免双斜杠或缺失开头斜杠,routes.php手动路由优先级高于注解路由。

Hyperf 中路由和控制器的对应关系不是靠“自动推断”或“约定优于配置”建立的,而是由注解扫描 + 路由注册两个明确阶段决定的。看不清这点,就容易误以为某个方法“应该被路由到”却 404。
Controller 注解类必须被 AnnotationScanner 扫描到
Hyperf 启动时(php bin/hyperf.php start)会触发 AnnotationScanner 扫描所有带 #[Controller] 或 #[AutoController] 的类。如果类没被扫描到,哪怕写对了注解,也不会注册任何路由。
- 检查类是否在
scan配置覆盖路径内(默认是app/和src/);config/autoload/annotations.php 中的scan→paths必须包含控制器所在目录 - 类命名空间必须正确,且文件名与类名严格一致(PSR-4 规范)
-
#[Controller]必须写在类声明上方,不能写在 trait 或父类里再继承过来——子类不会自动继承父类的路由注解 - 如果用了
#[AutoController],它只支持GET和POST,且方法名会直接转成小写 + 下划线路径(如getUserInfo→/get_user_info),不支持自定义 path
路由路径 = prefix + method path,拼接逻辑是纯字符串操作
#[Controller(prefix: "/api/v1")] 和 #[GetMapping(path: "users/{id}")] 拼出来的是 GET /api/v1/users/{id},中间**不加额外斜杠**,也不做 normalize。所以常见错误是:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- prefix 末尾写了
/,method path 开头又写了/→ 导致双斜杠/api/v1//users,fast-route 不匹配 - prefix 是
"api"(缺开头/),method path 是"/users"→ 最终变成GET api/users,非法路径 - path 值写成
"users/{id:\d+}",但请求 URL 是/api/v1/users/abc→ 匹配失败,返回 404(不是 400)
routes.php 里的手动路由优先级高于注解路由
如果你在 config/routes.php 里写了 Router::get('/users', ...),它会直接接管该路径,不管有没有同名的 #[Controller] 类存在。两者共存时,手动路由会“遮蔽”注解路由。
- 调试时可临时注释掉
routes.php全部内容,确认问题是否来自手动路由冲突 - 运行
php bin/hyperf.php route:list可查看当前已注册的所有路由(含来源:annotation 或 config) - 注意:这个命令只显示启动时加载的路由,热重载后修改的注解需重启服务才生效
最常被忽略的一点:Hyperf 的路由映射发生在启动阶段,不是运行时动态解析。改完注解不重启,等于没改;扫不到类、拼错 prefix、routes.php 冲突——这三类问题占了 90% 以上的“路由找不到”原因。


















