Laravel 表单验证:自定义验证规则 2 个改进

自定义验证规则

使用规则对象

Laravel 提供了许多有用的验证规则;同时也支持自定义规则。注册自定义验证规则的方法之一,就是使用规则对象。可以使用 Artisan 命令 make:rule 来生成新的规则对象。接下来,让我们用这个命令生成一个验证字符串是大写的规则。Laravel 会将新的规则存放在 app/Rules 目录中:

$ php artisan make:rule Uppercase

一旦创建了规则,我们就可以定义它的行为。规则对象包含两个方法: passesmessagepasses 方法接收属性值和名称,并根据属性值是否符合规则而返回 truefalsemessage 方法应返回验证失败时应使用的验证错误消息:

    <?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

    /**
     * 获取验证错误消息。
     *
     * @return string
     */
    public function message()
    {
        return trans('validation.uppercase');
    }

一旦规则对象被定义好后,你可以通过将规则对象的实例和其他验证规则一起来传递给验证器:

    use App\Rules\Uppercase;

    $request->validate([
        'name' => ['required', 'string', new Uppercase],
    ]);

使用闭包

如果你在应用程序中只需要一次自定义规则的功能,则可以使用闭包而不是规则对象。闭包接收属性的名称,属性的值如果验证失败则应该使用回调中的 $fail

    $validator = Validator::make($request->all(), [
        'title' => [
            'required',
            'max:255',
            function ($attribute, $value, $fail) {
                if ($value === 'foo') {
                    $fail($attribute.' is invalid.');
                }
            },
        ],
    ]);

使用扩展

注册自定义的验证规则的另一种方法是使用 Validator facade 中的 extend 方法。让我们在 服务容器 中使用这个方法来注册自定义验证规则:

    <?php

    namespace App\Providers;

    use Illuminate\Support\ServiceProvider;
    use Illuminate\Support\Facades\Validator;

    class AppServiceProvider extends ServiceProvider
    {
        /**
         * 引导任何应用程序。
         *
         * @return void
         */
        public function boot()
        {
            Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
                return $value == 'foo';
            });
        }

        /**
         * 注册服务提供器。
         *
         * @return void
         */
        public function register()
        {
            //
        }
    }

自定义的验证闭包接收四个参数:要被验证的属性名称 $attribute、属性的值 $value、传入验证规则的参数数组 $parameters 、以及 Validator 实列。

除了使用闭包,你也可以传入类和方法到 extend 方法中:

Validator::extend('foo', 'FooValidator@validate');

定义错误消息

你还需要为自定义规则定义错误信息。你可以使用内联自定义消息数组或者在验证语言文件中添加条目来实现这一功能。 消息应该被放到数组的第一位, 而不是在只用于存放属性指定错误信息的 custom 数组内:

    "foo" => "Your input was invalid!",

    "accepted" => "The :attribute must be accepted.",

    // 其余的验证错误消息...

当创建一个自定义验证规则时,你可能有时候需要为错误信息定义自定义占位符。可以通过创建自定义验证器然后调用 Validator 门面上的 replacer 方法。你可以在 服务容器boot 方法中执行如下操作:

    /**
     * 启动应用程序。
     *
     * @return void
     */
    public function boot()
    {
        Validator::extend(...);

        Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) {
            return str_replace(...);
        });
    }

隐式扩展

默认情况下, 当所要验证的属性不存在或包含由 required 规则定义的空值时,那么正常的验证规则,包括自定义扩展将不会执行。 例如,unique 规则将不会检验 null 值:

    $rules = ['name' => 'unique'];

    $input = ['name' => null];

    Validator::make($input, $rules)->passes(); // true

如果要求即使为空时也要验证属性,则必须要暗示属性是必须的。要创建这样一个「隐式」扩展, 可以使用 Validator::extendImplicit() 方法:

Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
        return $value == 'foo';
    });

「隐式」扩展只暗示该属性是必需的。至于它到底是缺失的还是空值这取决于你。

本文为 Wiki 文章,邀您参与纠错、纰漏和优化
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!