Laravel表单验证自定义验证规则

- 4 mins

使用规则对象

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

php artisan make:rule Uppercase

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

<?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');
}

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

/**
 * 使用规则对象自定义验证规则
 *
 * @param Request $request
 */
public function index(Request $request)
{
    $validator = Validator::make($request->all(), [
        'title' => [
            'required',
            new Uppercase
        ]
    ]);

    if ($validator->fails()) {
        dd($validator->errors());
    }
    dd($request->input('title'));
}

image-20190508153640419

使用闭包

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

/**
 * 使用闭包
 *
 * @param Request $request
 */
public function index1(Request $request)
{
    $validator = Validator::make($request->all(), [
        'title' => [
            'required',
            function($attribute, $value, $fail) {
                if ($value !== 'foo') {
                    return $fail($attribute.' is invalid.');
                }
            },
        ],
    ]);

    if ($validator->fails()) {
        dd($validator->errors());
    }
    dd($request->input('title'));

}

image-20190508153818819

使用扩展之extend

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

// 另外一个注册自定义验证规则的方法,就是使用 Validator facade 中的 extend 方法
Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
    return $value == 'foo';
});

// 当创建一个自定义验证规则时,你可能有时候需要为错误信息定义自定义占位符。
// 可以通过创建自定义验证器然后调用 Validator 门面上的 replacer 方法.
Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) {
    return "The {$attribute} not foo.";
});

// 如果要求即使为空时也要验证属性,则必须要暗示属性是必须的,要创建这样一个「隐式」扩展,
// 可以使用 Validator::extendImplicit() 方法:
Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
    return $value == 'foo';
});

image-20190508154217320

使用扩展之resolver

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

// 注册自定义验证器
$this->app['validator']->resolver(function ($translator, $data, $rules, $messages, $customAttributes) {
    return new CustomValidator($translator, $data, $rules, $messages, $customAttributes);
});

Validation\CustomValidator实现,也可用闭包。

<?php

namespace App\Validations;

use Illuminate\Validation\Validator;

class CustomValidator extends Validator
{
	// 默认规则名称为foo_chect
    protected function validateFooCheck($attribute, $value, $parameters)
    {
        return $value == 'foo';
    }

}

Validation.php配置message

'foo_check'         => 'The :attribute not foo',

image-20190508154231126

若增加Validator::replacer则显示为:

// 注册自定义验证器
        $this->app['validator']->resolver(function ($translator, $data, $rules, $messages, $customAttributes) {
            return new CustomValidator($translator, $data, $rules, $messages, $customAttributes);
        });
		// replacer优先级高于Validation.php文件
        Validator::replacer('foo_check', function ($message, $attribute, $rule, $parameters) {
            return "The {$attribute}不是foo .";
        });

image-20190508154623661

rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora