Laravel 提供了许多有用的验证规则,同时也支持自定义规则。注册自定义验证规则的方法之一,就是使用规则对象。可以使用 Artisan 命令 make:rule
来生成新的规则对象。接下来,让我们用这个命令生成一个验证字符串是大写的规则。Laravel 会将新的规则存放在 app/Rules
目录中:
php artisan make:rule Uppercase
一旦创建了规则,我们就可以定义它的行为。规则对象包含两个方法:passes
和 message
。 passes
方法接收属性值和名称,并根据属性值是否符合规则而返回 true
或者 false
。 message
方法应返回验证失败时应使用的验证错误消息:
<?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'));
}
如果你在应用程序中只需要一次自定义规则的功能,则可以使用闭包而不是规则对象。闭包接收属性的名称,属性的值以及如果验证失败应该调用的 $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'));
}
另外一个注册自定义验证规则的方法,就是使用 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';
});
还一个注册自定义验证规则的方法,就是使用 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',
若增加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 .";
});