🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## laravel自定义验证规则 ## 自定义验证规则 ### 使用规则对象 尽管 Laravel 提供了多种多样有用的校验规则;但您亦可进行自定义。注册自定义校验规则的方法之一便是使用规则对象。您可以使用`make:rule`生成新的规则对象。接下来,让我们使用该命令生成一个校验字符串是否是大写的规则, Laravel 会将新规则置于`app/Rules`目录中: ~~~php php artisan make:rule Uppercase ~~~ 当规则创建成功后,我们便可定义其行为。规则对象包含两个方法:`passes`和`message`。`passes`方法接收属性值及其名称,它应该返回以`true`和`false`表示的属性值是否通过验证的结果。`message`方法应该返回验证失败时使用的错误信息: ~~~php <?php namespace App\Rules; use Illuminate\Contracts\Validation\Rule; class Uppercase implements Rule { /** * 判断是否通过验证规则 * * @param string $attribute * @param mixed $value * @return bool */ public function passes($attribute, $value) { return strtoupper($value) === $value; } /** * 获取校验错误信息 * * @return string */ public function message() { return 'The :attribute must be uppercase.'; } } ~~~ 如果您想要从您的翻译文件中获取错误信息,您可以在您的`message`中使用`trans`助手方法: ~~~php /** * 获取校验错误信息 * * @return string */ public function message() { return trans('validation.uppercase'); } ~~~ 一旦定义了规则,您便可以通过将规则的实例化与其他校验规则一起传递给验证器: ~~~php use App\Rules\Uppercase; $request->validate([ 'name' => ['required', 'string', new Uppercase], ]); ~~~ ### 使用闭包 如果您的规则在应用中仅仅使用一次,那您便可使用闭包来代替规则对象。闭包函数接收属性的方法,属性的值以及在校验失败时的回调函数`$fail`: ~~~php $validator = Validator::make($request->all(), [ 'title' => [ 'required', 'max:255', function ($attribute, $value, $fail) { if ($value === 'foo') { $fail($attribute.' is invalid.'); } }, ], ]); ~~~ ### 使用扩展 另一种注册自定义校验规则的方式是在`Validator`[门面](https://learnku.com/docs/laravel/8.x/facades)中使用`extend`方法。接下来,让我们在[服务提供者](https://learnku.com/docs/laravel/8.x/providers)中使用这个方法来注册一个自定义校验规则: ~~~php <?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\Validator; class AppServiceProvider extends ServiceProvider { /** * 注册服务提供器 * * @return void */ public function register() { // } /** * 驱动应用服务 * * @return void */ public function boot() { Validator::extend('foo', function ($attribute, $value, $parameters, $validator) { return $value == 'foo'; }); } } ~~~ 自定义校验闭包函数接收四个参数:要被验证的属性名称`$attribute`,要被验证的属性值`$value`,传入验证规则的参数数组`$parameters`以及`Validator`实例。 您亦可通过传递类和方法到`extend`方法中来代替闭包: ~~~php Validator::extend('foo', 'FooValidator@validate'); ~~~ #### 定义错误信息 您还需要为您的自定义规则定义错误信息。您既可使用行内的自定义信息数组,也可将其添加到验证语言文件中以实现之。错误信息应该被置于数组的第一位,而不是放在只用于存放属性指定错误信息的`custom`数组内: ~~~php "foo" => "Your input was invalid!", "accepted" => "The :attribute must be accepted.", // 其余的错误信息... ~~~ 在创建自定义校验规则时,您可能需要为错误信息自定义占位符。您可以通过创建自定义验证器然后调用`Validator`门面的`replacer`方法以实现之。您可以在[服务提供者](https://learnku.com/docs/laravel/8.x/providers)的`boot`方法执行如下操作: ~~~php /** * 驱动应用程序 * * @return void */ public function boot() { Validator::extend(...); Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) { return str_replace(...); }); } ~~~ ### 隐式扩展 默认情况下,当要验证的属性不存在或者包含一个空字符串时,包含自定义扩展的校验规则是不会执行的。例如,[`unique`](https://learnku.com/docs/laravel/8.x/validation/9374#rule-unique)规则不会校验空字符串: ~~~php $rules = ['name' => 'unique:users,name']; $input = ['name' => '']; Validator::make($input, $rules)->passes(); // true ~~~ 如果想要实现即使属性为空,规则也要校验,那么就需要暗示该属性是必须的。要创建这样的 「隐式」扩展,请使用`Validator::extendImplicit()`方法: ~~~php Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) { return $value == 'foo'; }); ~~~ > 注意:「隐式」扩展仅仅暗示该属性是必须的。至于它到底是确实还是空值,这取决于你。 #### 隐式规则对象 如果您想在属性为空时执行规则对象,那么您应该实现`Illuminate\Contracts\Validation\ImplicitRule`接口。这个接口将充当验证器的 「标识接口」;因此,它不会包含任何您需要实现的方法。