跳转到主要内容

什么是自定义验证规则

Laravel 已内置丰富的验证规则,但在实际开发中经常需要应用特有的校验逻辑。使用自定义验证规则可以将可复用的校验逻辑定义为类或闭包,并像标准规则一样使用。 定义自定义规则主要有两种方式。
  • 规则对象 — 可复用性高、易于测试
  • 闭包 — 适合仅使用一次的简单规则

规则对象

生成规则类

使用 make:rule Artisan 命令生成新的规则类。生成的类会放在 app/Rules 目录下。

实现 ValidationRule 接口

在生成的类中实现 validate 方法。校验失败时通过调用 $fail 闭包报告错误。
传给 $fail 闭包的字符串中可以使用 :attribute 占位符,Laravel 会将其替换为字段名。

应用规则对象

将规则对象的实例传入校验数组即可。
在 Form Request 的 rules() 方法中也可以同样使用。

使用翻译键的错误消息

除了硬编码错误消息,也可以使用翻译键。
在翻译文件 lang/zh_CN/validation.php 中添加消息:

添加多条错误消息

要为同一字段报告多条错误,可以多次调用 $fail

基于闭包的规则

对于在应用中仅使用一次的简单规则,可以不创建类,直接用闭包定义。
闭包规则可以内联定义,非常轻量,但难以复用或独立测试。因此,多个地方共用的逻辑推荐拆分为规则对象。

Implicit 规则(值为空时也执行)

默认情况下,当字段为空或不存在时,自定义规则不会被执行。若希望即使值为空也执行规则,生成类时可加上 --implicit 选项。
生成的类会实现 ImplicitRule 接口。该接口本身没有额外方法,仅作为向 Laravel 传递的信号。
ImplicitRule 只是告诉 Laravel「该属性是必需的」。当值为空时是否真的判定为验证失败,取决于 validate 方法的实现。

数据访问

DataAwareRule — 访问整个表单的数据

如果需要基于其他字段的值来校验,可实现 DataAwareRule 接口。校验开始前 setData 方法会被自动调用。
使用示例:

ValidatorAwareRule — 访问 Validator 实例

若要访问 Validator 所拥有的全部信息(失败的规则、自定义消息等),可实现 ValidatorAwareRule 接口。

实战用例

中文字符检查

对全角/半角字符类型进行校验的规则。

电话号码格式校验

校验中国大陆电话号码格式的规则。

带租户 ID 的唯一性约束

多租户应用中常见的租户内唯一性约束。
1

创建规则类

2

在 Form Request 中使用

3

更新时排除自身 ID

更新已有记录时,需将自身 ID 排除后进行重复检查。

在 ServiceProvider 中注册规则

使用 Validator::extend() 追加规则

使用 Validator::extend() 可以让自定义规则以字符串形式('rule_name')使用。在 AppServiceProviderboot() 方法中注册。
通过 Validator::extend() 注册的规则可以用字符串指定。
Validator::extend() 是比规则对象更早的注册方式。新项目建议使用实现了 ValidationRule 接口的规则对象。

作为静态方法追加到 Rule 类

通过给 Rule Facade 添加宏,可以提供 Rule::myRule() 这样的流畅 API(Fluent API)。

内部实现细节

来看看 Illuminate\Validation\Validator 是如何调用自定义规则的。 Validator 内部由 validateAttribute() 处理每个字段。若规则实现了 ValidationRule 接口,则会调用 validateUsingCustomRule() 方法。
ImplicitRule 的处理通过 isImplicit() 方法判断,即便值为空也会执行规则检查。
可以同时实现 DataAwareRuleValidatorAwareRule。同时实现两个接口的类会同时注入这两者。

相关页面

验证(入门)

了解在 Controller 与 Form Request 中的标准验证方法。
最后修改于 2026年7月18日