有没有办法动态检索“合法”验证规则列表?我试图让我的模型自我验证自己的验证规则字符串,以确保它是准确的。即确保有人没有输入“requierd”。
我在 http://laravel.com/api/class-Illuminate.Validation.Validator.html 看到 getRules() ,但它只返回验证中使用的规则,而不是所有已知规则的列表。
没有官方 API 可以执行此操作,因此您需要使用反射。如果您查看
validate
方法的实现,您会发现规则只是验证对象上的方法(从对 make
的静态调用返回)
#File: vendor/laravel/framework/src/Illuminate/Validation/Validator.php
protected function validate($attribute, $rule)
{
//...
$method = "validate{$rule}";
if ($validatable && ! $this->$method($attribute, $value, $parameters, $this))
{
$this->addFailure($attribute, $rule, $parameters);
}
//...
}
这意味着我们可以使用反射来获取验证规则列表。此外,方法名称采用驼峰式命名法,并以大写字母开头(laravel 中的“studly case”),因此我们需要小写/下划线(laravel 中的“snake case”)来获取实际的验证规则名称。我们还将确定哪些规则具有
:
参数。不幸的是,没有办法得出每条规则期望的参数是什么。
$validator = Validator::make(array(), array());
//
$r = new ReflectionClass($validator);
$methods = $r->getMethods();
//filter down to just the rules
$methods = array_filter($methods, function($v){
if($v->name == 'validate') { return false; }
return strpos($v->name, 'validate') === 0;
});
//get the rule name, also if it has parameters
$methods = array_map(function($v){
$value = preg_replace('%^validate%','',$v->name);
$value = Str::snake($value);
$params = $v->getParameters();
$last = array_pop($params);
if($last && $last->name == 'parameters')
{
$value .= ':[params]';
}
return Str::snake($value);
}, $methods);
var_dump($methods);
如果用户通过扩展验证类添加了验证规则,则此技术将拾取任何自定义方法。但是,如果用户使用
Validation::extend
语法扩展了验证类,则上述技术将找不到这些规则。要获得这些规则,您需要执行类似的操作。
Validator::extend('customrule',function($attribute, $value, $parameters){
});
Validator::extend('anothercustom', 'FooValidator@validate');
$validator = Validator::make(array(), array());
$extension_methods = array();
foreach($validator->getExtensions() as $value=>$callback)
{
if(is_string($callback))
{
list($class, $method) = explode('@', $callback);
$r = new ReflectionClass($class);
$method = $r->getMethod($method);
}
else if(is_object($callback) && get_class($callback) == 'Closure')
{
$method = new ReflectionFunction($callback);
}
$params = $method->getParameters();
$last = array_pop($params);
if($last && $last->name == 'parameters')
{
$value .= ':[params]';
}
$extension_methods[] = $value;
}