动态获取Laravel验证规则列表?

时间:2014-08-29 21:40:02

标签: laravel laravel-4

有没有办法动态检索" legal"验证规则?我试图让我的模型自我验证自己的验证规则字符串,以确保它是准确的。即确保某人没有输入" requierd"。

我在http://laravel.com/api/class-Illuminate.Validation.Validator.html看到了getRules(),但它只返回验证中使用的统治,而不是所有已知规则的列表。

1 个答案:

答案 0 :(得分:1)

没有官方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讲话中的“精巧案例”)所以我们需要小写/下划线(laravel讲话中的“蛇案”)以获得实际的验证规则名称。我们还将确定哪些规则具有:个参数。不幸的是,没有办法推导出每个规则期望参数的

$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;

}