hyperf-plus / validate
hyperf-plus validate 基于 hyperf/validation 的路由验证适配器,支持注解式验证
Installs: 8 606
Dependents: 2
Suggesters: 2
Security: 0
Stars: 4
Watchers: 1
Forks: 2
Open Issues: 0
pkg:composer/hyperf-plus/validate
Requires
- php: >=8.1
- hyperf/di: ^3.1.0
- hyperf/http-message: ^3.1.0
- hyperf/translation: ^3.1.0
- hyperf/utils: ^3.1.0
- hyperf/validation: ^3.1.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- mockery/mockery: ^1.5
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^9.5
Suggests
- ext-json: Required to use JSON.
- ext-swoole: Required to use Swoole coroutine features for better performance.
README
基于 hyperf/validation 的路由验证适配器,支持注解式验证。
特性
- 🚀 基于 Laravel Validation 规则,功能强大
- 📝 注解式验证,代码简洁优雅
- ⚡ 规则缓存,高性能
- 🎯 专注路由验证,职责单一
- 🔧 完全兼容 hyperf/validation 所有规则
安装
composer require hyperf-plus/validate
配置
1. 发布配置文件(可选)
php bin/hyperf.php vendor:publish hyperf-plus/validate
2. 安装语言包(必需)
composer require hyperf/translation php bin/hyperf.php vendor:publish hyperf/translation
配置 config/autoload/translation.php:
return [ 'locale' => 'zh_CN', 'fallback_locale' => 'en', 'path' => BASE_PATH . '/storage/languages', ];
使用方法
基础用法
<?php namespace App\Controller; use HPlus\Route\Annotation\PostApi; use HPlus\Route\Annotation\ApiController; use HPlus\Validate\Annotations\RequestValidation; #[ApiController(prefix: '/api/users')] class UserController { #[PostApi(path: '')] #[RequestValidation( rules: [ 'name' => 'required|string|max:50', 'email' => 'required|email|unique:users,email', 'password' => 'required|string|min:6|confirmed', 'age' => 'nullable|integer|between:18,100', ], messages: [ 'name.required' => '用户名不能为空', 'email.unique' => '该邮箱已被注册', ] )] public function create() { // 验证通过后的逻辑 return ['message' => 'success']; } }
验证模式
1. 验证请求体(rules)
验证 POST/PUT 请求体数据:
#[RequestValidation(
rules: ['name' => 'required', 'email' => 'required|email']
)]
2. 验证查询参数(queryRules)
验证 URL 查询参数(GET 请求参数):
#[GetApi(path: '')] #[RequestValidation( queryRules: [ 'page' => 'required|integer|min:1', 'size' => 'required|integer|between:1,100', 'keyword' => 'nullable|string|max:50', ] )] public function list() { // ... }
3. 同时验证 Query 和 Body
使用 queryRules 和 rules 分别验证:
#[PostApi(path: '/search')] #[RequestValidation( queryRules: [ 'page' => 'required|integer|min:1', // 验证 URL 查询参数 'size' => 'required|integer|between:1,100', ], rules: [ 'filters' => 'nullable|array', // 验证请求体 'sort' => 'nullable|array', ] )] public function search() { // ... }
4. 请求体数据格式(mode)
mode 参数控制请求体数据的解析方式:
#[RequestValidation(
rules: ['name' => 'required'],
mode: 'json' // 默认值,可选:json | form | xml
)]
自定义错误消息
#[RequestValidation(
rules: [
'email' => 'required|email',
'password' => 'required|min:6',
],
messages: [
'email.required' => '邮箱地址不能为空',
'email.email' => '邮箱格式不正确',
'password.min' => '密码至少需要6个字符',
]
)]
自定义字段名称
#[RequestValidation(
rules: [
'user_email' => 'required|email',
],
attributes: [
'user_email' => '用户邮箱',
]
)]
// 错误消息将显示:"用户邮箱格式不正确",而不是"user_email格式不正确"
停止首个失败
默认验证所有字段,返回所有错误。如果只想返回第一个错误:
#[RequestValidation(
rules: ['email' => 'required|email'],
stopOnFirstFailure: true
)]
支持的验证规则
完全支持 Laravel Validation 所有规则,包括但不限于:
基础规则
required- 必填nullable- 可为空string- 字符串integer- 整数numeric- 数字boolean- 布尔值array- 数组json- JSON 字符串
字符串规则
email- 邮箱格式url- URL 格式ip- IP 地址uuid- UUID 格式alpha- 纯字母alpha_num- 字母和数字alpha_dash- 字母、数字、破折号、下划线regex:pattern- 正则表达式
数值规则
min:value- 最小值max:value- 最大值between:min,max- 范围size:value- 大小gt:field- 大于某字段gte:field- 大于等于某字段lt:field- 小于某字段lte:field- 小于等于某字段
日期规则
date- 日期格式date_format:format- 指定日期格式before:date- 早于某日期after:date- 晚于某日期before_or_equal:date- 早于或等于after_or_equal:date- 晚于或等于
数组规则
in:foo,bar,...- 在指定值中not_in:foo,bar,...- 不在指定值中array- 数组类型distinct- 数组不重复
数据库规则
unique:table,column,except,idColumn- 唯一性exists:table,column- 存在性
文件规则
file- 文件image- 图片mimes:jpg,png,...- 文件类型max:value- 文件大小(KB)
关系规则
confirmed- 确认字段(需要field_confirmation)same:field- 与某字段相同different:field- 与某字段不同required_if:field,value- 条件必填required_with:field- 当某字段存在时必填required_without:field- 当某字段不存在时必填
更多规则请参考:https://laravel.com/docs/validation#available-validation-rules
高级用法
自定义验证规则
在 config/autoload/dependencies.php 中扩展验证器:
use Hyperf\Validation\Contract\ValidatorFactoryInterface; use Hyperf\Validation\ValidatorFactory; return [ ValidatorFactoryInterface::class => function ($container) { $factory = $container->get(ValidatorFactory::class); // 注册自定义规则 $factory->extend('phone', function ($attribute, $value, $parameters, $validator) { return preg_match('/^1[3-9]\d{9}$/', $value); }); // 自定义错误消息 $factory->replacer('phone', function ($message, $attribute, $rule, $parameters) { return str_replace(':attribute', $attribute, ':attribute 必须是有效的手机号'); }); return $factory; }, ];
使用自定义规则:
#[RequestValidation(
rules: ['mobile' => 'required|phone']
)]
嵌套数组验证
#[RequestValidation(
rules: [
'users' => 'required|array',
'users.*.name' => 'required|string',
'users.*.email' => 'required|email',
'users.*.age' => 'nullable|integer|min:18',
]
)]
条件验证
#[RequestValidation(
rules: [
'type' => 'required|in:person,company',
'id_card' => 'required_if:type,person|size:18',
'business_license' => 'required_if:type,company',
]
)]
性能优化
规则缓存
验证规则会在首次请求时解析并缓存在内存中,后续请求直接使用缓存,无需重复解析注解。
查看缓存统计
use HPlus\Validate\Aspect\ValidationAspect; $stats = ValidationAspect::getCacheStats(); // [ // 'rule_hits' => 1000, // 'rule_misses' => 10, // 'total_requests' => 1010, // 'rule_hit_rate' => '99.01%', // 'rule_cache_size' => 10, // ]
清空缓存
ValidationAspect::clearCache();
错误处理
验证失败会抛出 HPlus\Validate\Exception\ValidateException 异常,状态码为 422。
建议在全局异常处理器中统一处理:
<?php namespace App\Exception\Handler; use HPlus\Validate\Exception\ValidateException; use Hyperf\ExceptionHandler\ExceptionHandler; use Psr\Http\Message\ResponseInterface; use Throwable; class ValidationExceptionHandler extends ExceptionHandler { public function handle(Throwable $throwable, ResponseInterface $response) { if ($throwable instanceof ValidateException) { return $response ->withStatus(422) ->withHeader('Content-Type', 'application/json') ->withBody(new SwooleStream(json_encode([ 'code' => 422, 'message' => $throwable->getMessage(), ], JSON_UNESCAPED_UNICODE))); } return $response; } public function isValid(Throwable $throwable): bool { return $throwable instanceof ValidateException; } }
RuleParser(供 Swagger 使用)
RuleParser 类用于将验证规则转换为 JSON Schema,主要供 hyperf-plus/swagger 插件使用:
use HPlus\Validate\RuleParser; // 单个规则转换 $schema = RuleParser::ruleToJsonSchema('required|string|max:50|email'); // ['type' => 'string', 'maxLength' => 50, 'format' => 'email'] // 批量规则转换 $schema = RuleParser::rulesToJsonSchema([ 'name|姓名' => 'required|string|max:50', 'age|年龄' => 'nullable|integer|between:18,100', ]); // 返回完整的 JSON Schema
与旧版本的区别
旧版(已弃用)
#[RequestValidation(
rules: ['email' => 'required|email'],
validate: UserValidator::class, // ❌ 不再需要
scene: 'create', // ❌ 不再需要
filter: true, // ✅ 保留
security: true, // ✅ 保留
batch: true, // ✅ 改为 stopOnFirstFailure
dateType: 'json' // ✅ 改为 mode
)]
新版(推荐)
#[RequestValidation(
rules: ['email' => 'required|email'], // ✅ 请求体验证规则
queryRules: ['page' => 'integer'], // ✅ 查询参数验证规则
messages: [], // ✅ 自定义消息
attributes: [], // ✅ 字段别名
mode: 'json', // ✅ 请求体解析模式
filter: false, // ✅ 过滤多余字段
security: false, // ✅ 安全模式
stopOnFirstFailure: false // ✅ 停止策略
)]
参数说明
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
rules |
array | [] |
请求体验证规则 (Laravel validation 规则) |
queryRules |
array | [] |
查询参数验证规则 |
messages |
array | [] |
自定义错误消息 |
attributes |
array | [] |
字段别名(用于错误消息) |
mode |
string | 'json' |
请求体数据解析模式:json / form / xml |
filter |
bool | false |
是否过滤多余字段(只保留规则中定义的字段) |
security |
bool | false |
安全模式(请求中有未定义字段时抛出异常) |
stopOnFirstFailure |
bool | false |
是否在第一个失败时停止验证 |
迁移指南
如果你正在从旧版本迁移:
- ✅ 保留
rules参数 - ❌ 移除
validate和scene参数(改用内联规则) - ✅ 保留
filter和security参数 - ✅ 将
dateType改为mode - ✅ 将
batch: false改为stopOnFirstFailure: true
常见问题
1. 验证不生效?
检查是否正确安装了 hyperf/validation 和 hyperf/translation。
2. 错误消息是英文?
确保配置了中文语言包,参考"配置"部分。
3. 如何验证 GET 请求参数?
使用 queryRules 参数。
4. 如何同时验证 query 和 body?
同时使用 queryRules(验证查询参数)和 rules(验证请求体)。
License
Apache-2.0