Hyperf路由中HTTP方法必须显式声明,如#[HttpGet]或#[HttpPost],不支持混用或推断;动态参数校验需在path中用正则(如{id:\d+})前置拦截,而非控制器内手动判断。

Hyperf 路由中,GET 和 POST 的限制不是“选配”,而是必须显式声明的契约——不写 methods 或错用注解,请求根本进不了控制器。
Hyperf 注解路由必须用 #[HttpGet] 或 #[HttpPost]
Hyperf 不支持像 Laravel 那样在 #[GetMapping] 里混用方法名或靠路径推断。它把 HTTP 方法语义直接绑定到注解名上:
-
#[HttpGet(path: "/user/{id:\d+}")]→ 只响应 GET,其他方法(如 POST /user/123)直接返回405 Method Not Allowed -
#[HttpPost(path: "/login")]→ 只响应 POST,GET /login 同样是 405 - 不存在
#[HttpMethod(methods: ["GET", "POST"])]这种写法;要允许多方法,得写两个注解,或改用Router::addRoute()
注意:#[GetMapping] 是 #[HttpGet] 的别名(底层等价),但语义更模糊;建议优先用 #[HttpGet],避免和旧版文档混淆。
动态参数校验必须写在 path 里,不能靠控制器判断
比如想让 /user/{id} 只接受数字 ID,你不能只写 #[HttpGet(path: "/user/{id}")] 然后在方法里 if (!is_numeric($id)) { throw new BadRequestException(); } —— 这已经晚了。
- 正确姿势:
#[HttpGet(path: "/user/{id:\d+}")],\d+在路由匹配阶段就过滤掉非数字请求,返回404 Not Found - 错误写法:
#[HttpGet(path: "/user/{id}")]+ 手动校验 → 白耗一次容器解析、中间件执行、DB 连接准备 - 正则约束只对花括号内有效:
{id:[0-9]+}和{id:\d+}等价;但{id:\d*}允许空字符串,需慎用
用 Router::addRoute() 时 methods 参数必须是数组且全大写
配置文件方式(config/routes.php)更灵活,但也更容易踩坑:
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
- ✅ 正确:
Router::addRoute(['GET', 'HEAD'], '/status', 'App\Controller\HealthController::check'); - ❌ 错误:
Router::addRoute('GET, HEAD', ...)(字符串 → 405) - ❌ 错误:
Router::addRoute(['get'], ...)(小写 → 匹配失败,静默降级为 GET-only) - ⚠️ 注意:
HEAD不会自动继承自GET;如果只写['GET'],HEAD /status仍会 405,除非显式加上
另外,Router::get() 是 Router::addRoute(['GET'], ...) 的语法糖,但不支持多方法;要多方法必须用 addRoute。
POST 接口光限方法不够,Content-Type 和 body 解析必须同步处理
#[HttpPost] 或 Router::post() 只拦方法,不拦内容。常见翻车点:
- 前端发
Content-Type: text/plain的 POST →$request->getParsedBody()为空,$request->getJson()报错 - 没配
bodyParser中间件 → JSON 请求体不会自动解析成数组,$request->json()返回 null - 表单提交却漏了
application/x-www-form-urlencoded支持 →$request->input('xxx')拿不到值
建议在对应路由加中间件:middleware: [BodyParserMiddleware::class],或全局启用(见 config/autoload/middlewares.php)。否则,methods=["POST"] 就只是个门牌号,门开着,但屋里没人接招。
真正难的不是写对注解,而是想清楚:这个接口到底该被谁、以什么格式、在什么条件下访问。路由规则一旦生效,就再没有“差不多可以”的余地。


















