Hyperf 3.0 注册自定义验证规则需遵循协程安全原则,通过实现 Rule 接口、配置 extensions 别名、依赖注入绑定及使用协程 I/O 实现,禁用同步调用与静态变量。

Hyperf 3.0 中注册自定义验证规则,关键在于**规则类注册 + 协程安全实现**,不能沿用传统同步方式(如 Laravel 的静态注册),否则在协程环境下可能引发状态污染或规则丢失。
自定义验证规则类(协程安全)
推荐将规则封装为独立类,实现 Hyperf\Validation\Contracts\Rule 接口,避免闭包或静态变量导致的协程上下文混乱:
- 创建类
App\Validate\Rule\ChineseMobile,构造函数不保存请求数据,校验逻辑中所有 I/O 操作需使用协程客户端(如CoMySQL、Redis::get()) - 重写
passes($attribute, $value)方法,返回布尔值;message()返回提示语(支持语言包占位符,如:attribute) - 若需查库去重(如手机号唯一性),务必用
go或Coroutine::create包裹异步操作,不可用DB::table()->where()->exists()这类同步调用
注册到验证器工厂
在 config/autoload/dependencies.php 中绑定规则类,确保每次验证都获得新实例:
- 添加依赖映射:
'App\Validate\Rule\ChineseMobile' => \App\Validate\Rule\ChineseMobile::class - 在验证器中直接使用字符串名引用:
'phone' => ['required', 'chinese_mobile'] - 规则别名需在
config/autoload/validation.php的'extensions'数组中声明,例如:
`'chinese_mobile' => App\Validate\Rule\ChineseMobile::class`
在表单请求中使用
继承 Hyperf\Validation\Request\FormRequest 后,在 rules() 方法里调用即可:
- 支持数组写法:
'phone' => ['required', new ChineseMobile()] - 也支持字符串别名:
'phone' => ['required', 'chinese_mobile'](前提是已配置extensions) - 若规则需传参(如指定表名),建议用构造函数注入,不要依赖运行时动态拼接规则字符串
手动验证时注入规则
控制器中通过 $this->validationFactory 创建验证器时,可显式传入扩展规则:
- 调用
make($data, $rules, $messages, $customAttributes, $extensions)第五个参数传入规则映射数组 - 或更推荐:提前在
validation.php配置好extensions,全局生效,无需每次手动传 - 注意:
$extensions数组键为规则名(小写蛇形),值为完整类名字符串


















