什么是自定义验证规则
Laravel 已内置丰富的验证规则,但在实际开发中经常需要应用特有的校验逻辑。使用自定义验证规则可以将可复用的校验逻辑定义为类或闭包,并像标准规则一样使用。 定义自定义规则主要有两种方式。- 规则对象 — 可复用性高、易于测试
- 闭包 — 适合仅使用一次的简单规则
规则对象
生成规则类
使用make:rule Artisan 命令生成新的规则类。生成的类会放在 app/Rules 目录下。
实现 ValidationRule 接口
在生成的类中实现validate 方法。校验失败时通过调用 $fail 闭包报告错误。
$fail 闭包的字符串中可以使用 :attribute 占位符,Laravel 会将其替换为字段名。
应用规则对象
将规则对象的实例传入校验数组即可。rules() 方法中也可以同样使用。
使用翻译键的错误消息
除了硬编码错误消息,也可以使用翻译键。lang/zh_CN/validation.php 中添加消息:
添加多条错误消息
要为同一字段报告多条错误,可以多次调用$fail。
基于闭包的规则
对于在应用中仅使用一次的简单规则,可以不创建类,直接用闭包定义。Implicit 规则(值为空时也执行)
默认情况下,当字段为空或不存在时,自定义规则不会被执行。若希望即使值为空也执行规则,生成类时可加上--implicit 选项。
ImplicitRule 接口。该接口本身没有额外方法,仅作为向 Laravel 传递的信号。
数据访问
DataAwareRule — 访问整个表单的数据
如果需要基于其他字段的值来校验,可实现DataAwareRule 接口。校验开始前 setData 方法会被自动调用。
ValidatorAwareRule — 访问 Validator 实例
若要访问 Validator 所拥有的全部信息(失败的规则、自定义消息等),可实现ValidatorAwareRule 接口。
实战用例
中文字符检查
对全角/半角字符类型进行校验的规则。电话号码格式校验
校验中国大陆电话号码格式的规则。带租户 ID 的唯一性约束
多租户应用中常见的租户内唯一性约束。1
创建规则类
2
在 Form Request 中使用
3
更新时排除自身 ID
更新已有记录时,需将自身 ID 排除后进行重复检查。
在 ServiceProvider 中注册规则
使用 Validator::extend() 追加规则
使用Validator::extend() 可以让自定义规则以字符串形式('rule_name')使用。在 AppServiceProvider 的 boot() 方法中注册。
Validator::extend() 注册的规则可以用字符串指定。
作为静态方法追加到 Rule 类
通过给Rule Facade 添加宏,可以提供 Rule::myRule() 这样的流畅 API(Fluent API)。
内部实现细节
来看看Illuminate\Validation\Validator 是如何调用自定义规则的。
Validator 内部由 validateAttribute() 处理每个字段。若规则实现了 ValidationRule 接口,则会调用 validateUsingCustomRule() 方法。
ImplicitRule 的处理通过 isImplicit() 方法判断,即便值为空也会执行规则检查。
相关页面
验证(入门)
了解在 Controller 与 Form Request 中的标准验证方法。