路由路径参数必须用正则约束,@validate注解完全不校验它;正确做法是在#[getmapping]或router::addroute()的path中直接写如"/user/{id:d+}",确保非法id(如abc)在路由匹配阶段即返回404。

路由路径参数必须用正则约束,不能靠@Validate注解
Hyperf 的 @Validate 注解**完全不处理路由路径参数**(如 /user/{id} 中的 id),它只校验 query、body 和 form。想让 {id} 必须是数字,得在路由定义阶段就卡死——这是 FastRoute 层的职责,不是验证器的事。
常见错误是写了 @Validate(["id" => "required|integer"]) 却发现非法 id(比如 /user/abc)照样进控制器,因为请求根本没被拦住。
- 正确做法:在
#[GetMapping]或Router::addRoute()的 path 字段里直接写正则,例如"/user/{id:d+}" - 正则必须写在
{}内,d+表示至少一位数字;[a-z]+、[0-9a-f]{32}也合法 - 如果没写正则(如
"/user/{id}"),FastRoute 会把任意字符串都匹配进来,后续全靠你手动is_numeric()或抛异常
#[GetMapping] 路径正则写法与常见陷阱
#[GetMapping(path: "/user/{id:d+}")] 看似简单,但几个细节一错就 404 或透传:
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
- 路径中不能有多余空格:
path: "/user/{id:d+} "(末尾空格)会导致路由注册失败,php bin/hyperf.php route:list里压根看不到这条 - 正则里的反斜杠要双写:PHP 字符串中
d需写成\d,但注解属性值是 PHP 常量,直接写d+即可(框架底层会正确转义) - 多个路径段都要显式声明:想匹配
/user/123/profile,不能只写"/user/{id}/profile",必须写"/user/{id:\d+}/profile",否则{id}段不校验 - 可选段要用方括号:如
"/user/{id:\d+}[/{name:[a-z]+}]",注意[ ]是 FastRoute 语法,不是正则
需要更复杂校验?手动取参 + validator()->make()
当路径参数需查库(如 exists:users,id)、或规则超出正则能力(如“必须是偶数”),就得放弃纯路由层拦截,在控制器里手动校验:
public function show(RequestInterface $request)
{
$id = $request->route()->parameters()['id'] ?? null;
$validator = $this->validatorFactory->make(
['id' => $id],
['id' => 'required|exists:users,id'],
['id.exists' => '用户不存在']
);
if ($validator->fails()) {
throw new ValidationException($validator);
}
// 继续业务逻辑
}
- 务必用
$request->route()->parameters()取值,别用$request->input('id')—— 后者只读 query/body - 这种写法绕过了
ValidationMiddleware,所以不会自动返回 422,得自己 throwValidationException - 如果项目已启用全局
ValidationExceptionHandler,这个异常会被自动转成标准 JSON 响应
为什么 /user/{id} 访问时报 404?先检查这三处
不是代码写错了,而是环境或配置没对齐:
- 确认
config/autoload/annotations.php里'scan' => true且'paths'包含了控制器所在目录(如'app/Controller') - 检查终端启动日志:运行
php bin/hyperf.php start后,有没有[INFO] Route registered: GET /user/{id:d+}这类提示;没有说明注解根本没扫到 - 用
curl -v http://127.0.0.1:9501/user/123测试,别用浏览器——浏览器可能自动补斜杠或重定向,导致实际请求变成/user/123/(末尾多斜杠)而匹配失败
路径参数校验的边界很清晰:正则管“格式”,验证器管“语义”。混用或漏掉任一环,都会让非法数据溜进业务逻辑。










