@Validation注解失效主因是未正确use Hyperf\Validation\Annotation\Validation;rules须为合法PHP数组字面量;注解不自动挂载验证结果,需手动调用$validator->validated()或改用FormRequest。

Validation注解不生效,@Validation 被完全忽略
Hyperf 的 @Validation 注解失效,最常见的原因是注解类没被正确引入——不是写错了,而是根本没 use。Hyperf 自带的验证注解位于 Hyperf\Validation\Annotation\Validation,但很多人会误用 Laravel 风格的 Illuminate\Foundation\Http\FormRequest 或直接抄错命名空间。
检查你的控制器方法上方是否写了:
@Validation
然后确认文件顶部有且仅有这一行引入:
use Hyperf\Validation\Annotation\Validation;
常见错误包括:
- 漏掉
use,只写了注解,PHP 解析器压根不认识这个标签 - 写成
use Hyperf\Contract\ValidationInterface;(这是接口,不是注解类) - 写成
use App\Annotation\Validation;(自定义注解未注册或路径错误) - IDE 自动补全导入了
Hyperf\HttpServer\Annotation\Middleware等无关类,干扰判断
@Validation 报错 “Class not found” 或 “Annotation is not a class”
这类错误通常出现在注解解析阶段,说明 AnnotationReader 尝试反射该注解类时失败。Hyperf 默认只扫描 App 和 Hyperf 命名空间下的注解,如果你把 Validation 注解放在非标准路径(比如 App\Annotations\Validation),必须显式注册。
修复方式分两步:
- 确保自定义注解类继承
Hyperf\Di\Annotation\AbstractAnnotation - 在
config/autoload/annotations.php中添加扫描路径:'scan' => ['paths' => ['app/Annotations']] - 若使用的是 Hyperf 3.0+,还需确认
Hyperf\Di\Aop\ProxyManager已启用(默认开启,但某些精简部署可能关了)
注意:Hyperf 官方 @Validation 注解无需额外注册,只要命名空间对、use 对,就一定能被识别。
参数校验始终跳过,rules 字段不解析
@Validation 支持传参,例如 @Validation(rules={"name": "required|string|max:20"}),但这里极易出错——Hyperf 要求 rules 必须是合法 PHP 数组字面量语法,**不能用单引号包裹整个字符串,也不能混用引号嵌套**。
以下写法全部无效:
@Validation(rules='{"name": "required"}')
@Validation(rules={"name": 'required'})
正确写法只有一种:
@Validation(rules={"name": "required|string|max:20"})
另外注意:
-
rules键名必须对应请求参数名(如 POST body 中的字段),不是 DTO 属性名 - 如果用了
@RequestBody+ DTO,@Validation仍作用于原始请求数据,不是 DTO 实例 - Hyperf 不支持在
@Validation中引用变量或调用函数,所有规则必须静态写出
验证通过但 $request->validated() 返回空数组
这不是注解问题,而是使用时机错误。@Validation 只负责拦截非法请求并抛出 ValidationException,它**不会自动挂载验证结果到 Request 对象上**。Hyperf 中想拿到已过滤数据,得手动调用验证器:
$validator = $this->validationFactory->make($request->all(), $rules);<br>if ($validator->fails()) { ... }<br>$data = $validator->validated();
或者更推荐的方式:改用 FormRequest 类,它内置了 validated() 方法支持:
public function rules() { return ["name" => "required"]; }<br>public function authorize() { return true; }
此时在控制器中接收 MyFormRequest $request,再调用 $request->validated() 才有效。
别指望 @Validation 注解能帮你省掉这一步——它只做守门员,不负责整理行李。


















