验证器怎么创建的,谁创建的
Laravel 文档调用验证器,除了通过控制器,还有就是通过Facades的方式创建验证器对象。Validator::make($data,$rule,$message)。
config/app.php 中注册了'Validator' => Illuminate\Support\Facades\Validator::class。
<?php
namespace Illuminate\Support\Facades;
/**
* @see \Illuminate\Validation\Factory
*/
class Validator extends Facade
{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
return 'validator';
}
}
从上面可以看出,Validator的实际实现类是容器中的validator对象,那这个validator对象是哪个?
<?php
namespace Illuminate\Foundation;
...
class Application extends Container implements ApplicationContract, HttpKernelInterface
{
...
public function registerCoreContainerAliases()
{
foreach ([
...
'validator'=> [
\Illuminate\Validation\Factory::class,
\Illuminate\Contracts\Validation\Factory::class
],
])
...
}
...
}
可以看出,最终创建验证器是通过实现\Illuminate\Contracts\Validation\Factory接口的\Illuminate\Validation\Factory类创建的。再来看看,这个工厂类怎么创建实际的验证器的。
//\Illuminate\Contracts\Validation\Factory 源码
protected function resolve(array $data, array $rules, array $messages, array $customAttributes)
{
if (is_null($this->resolver)) {
return new Validator(
$this->translator,
$data,
$rules,
$messages,
$customAttributes
);
}
return call_user_func(
$this->resolver,
$this->translator,
$data,
$rules,
$messages,
$customAttributes
);
}
到这里,可以看出Laravel的验证器的创建都是通过特定的工厂类创建。
如果需要自定义验证器类(比如我需要把5.8的一些新功能迁移到5.5的版本上),有两种方式:
一,创建一个自定义的工厂类。然后在AppServiceProvider中重新绑定新的验证器工厂创建类;
二,AppServiceProvider中通过resolver方法设置工厂类的resolver属性,接管验证器的实例化,例如:
Validator::resolver(function($translator, $data, $rules, $messages, $customAttributes){
return new ExtendValidator($translator, $data, $rules, $messages, $customAttributes);
});
如何自定义验证规则
Laravel本身提供了很多通用的参数验证规则,但是对于一些特定的场景,还是需要提供验证规则的扩展。
Laravel验证规则的扩展有两种方式。
1 通过extend方法扩展
//这是一个简单的参数比较的验证规则,Laravel5.8中提供,Laravel5.5中未提供
//验证规则如下: 'max_num'=>'gte:min',
Validator::extend('gte',function($attribute, $value, $parameters, $validator){
if($value>=data_get($validator->getData(),$parameters[0]))
{
return true;
}
return false;
});