【问题标题】:Laravel Multiple Custom ValidationLaravel 多重自定义验证
【发布时间】:2014-08-31 05:17:22
【问题描述】:

我想添加多个自定义验证,每个都作为自己的文件。

到目前为止,我已将app/start/global.php 文件修改为

global.php

ClassLoader::addDirectories(array(
    app_path().'/commands',
    app_path().'/controllers',
    app_path().'/models',
    app_path().'/database/seeds',
    app_path().'/validators'        // <--- Added this folder
));

// Only the first resolver works. 
// I cannot seem to have multiple of these files

Validator::resolver(function($translator, $data, $rules, $messages) 
{
    return new ScheduleValidator($translator, $data, $rules, $messages);
});

Validator::resolver(function($translator, $data, $rules, $messages) 
{
    return new UserValidator($translator, $data, $rules, $messages);
});

我的每个验证文件都在/validators

ScheduleValidator.php

class ScheduleValidator extends Illuminate\Validation\Validator
{
    protected $implicitRules = array('Required', 'RequiredWith', 'RequiredWithout', 'RequiredIf', 'Accepted', 'RequiredWithoutField');
    public function __construct(\Symfony\Component\Translation\TranslatorInterface $translator, $data, $rules, $messages = array())
    {
        parent::__construct($translator, $data, $rules, $messages);
        $this->isImplicit('fail');
    }

    /**
    * Validates type to be of the type 'common', 'template', or 'revision'
    */
    public function validateTypeSchedule($attribute, $value, $parameters = null)
    {
        $valid_types = ['template', 'common', 'revision'];
        return in_array($value, $valid_types);
    }

    // and the other validators ...
}

那么如何添加多个这些验证器?

【问题讨论】:

    标签: php validation laravel


    【解决方案1】:

    我的猜测是,对 Validator::resolver 的调用只是设置了一个尚未设置的值,因此第二次和以后的调用将被忽略。

    您真正需要的是对Validator::resolver 的一次调用,并包含您选择在闭包中使用哪个验证器的逻辑。它看起来像这样:

    Validator::resolver(function($translator, $data, $rules, $messages) 
    {
        // perform a test to figure out what kind of validator to return
        if ($schedule) {
            return new ScheduleValidator($translator, $data, $rules, $messages);
        } else {
            return new UserValidator($translator, $data, $rules, $messages);
        }
    });
    

    诀窍将是 if 测试 - 我不确定在那里做什么。首先想到的是检查$data的类型:

    if ($data instanceof Schedule) {
    

    但是验证器将接收一个数组而不是$data 的对象。所以这意味着要么 a) 您需要检查数组值并弄清楚您要验证的内容是什么,或者 b) 在验证数组时需要向数组添加标志或类型值。第二个可能更容易,更健壮一些。例如:

    // in the Schedule controller
    $data = Input::all();
    $data["type"] = "schedule";
    $validator = Validator::make($data, $rules);
    
    // in global.php
    Validator::resolver(function($translator, $data, $rules, $messages) 
    {
        // perform a test to figure out what kind of validator to return
        if ($data["type"]=="schedule") {
            return new ScheduleValidator($translator, $data, $rules, $messages);
        } else {
            return new UserValidator($translator, $data, $rules, $messages);
        }
    });
    

    不幸的是,这不是一个非常优雅的解决方案。为了改进它,您可以创建一个库,其唯一任务是解析所需的验证器类型。

    【讨论】:

    • 好的,谢谢,我试试看。但是为什么没有一种简单的方法来做到这一点呢?我不认为这是一个非常不现实的事情。它可以让您的自定义验证与其模型分开,特别是在项目变大的情况下。
    • 是的,我不能说我不同意你的观点。如果您对基于模型的验证感兴趣,可以使用 Laravel 包来处理模型中的验证。我不记得它的名字了。
    【解决方案2】:

    我通过创建所有单独的验证器特征来解决这个问题,因此我的一个自定义验证器可以简单地“使用”我的特征并且仍然保持它们分开。

    我的验证者:

    <?php
    
    use Illuminate\Validation\Validator as LaravelValidator;
    
    class CustomValidator extends LaravelValidator {
        use PhoneValidatorTrait;
    
    }
    

    我的特点:

    <?php
    
    class PhoneValidatorTrait {
        public function validateSomething(){ ... }
    }
    

    解析器:

    <?php
    
    Validator::resolver(function($translator, $data, $rules, $messages)
    {
        return new CustomValidator($translator, $data, $rules, $messages, []);
    });
    

    【讨论】:

      【解决方案3】:

      例如使用自定义验证器创建一个类:

      <?php namespace Acme\Validators;
      
      use Illuminate\Validation\Validator as Validator;
      use DB;
      use Input;
      use Request;
      
      class CustomValidator extends Validator {
      
          public function validateUniqueWith($attribute, $value, $parameters)
          {
              $table = $parameters[0];
      
              $query = DB::table($table)
                  ->where($parameters[1], Input::get($parameters[1]))
                  ->where($attribute, $value);
      
              if (isset($parameters[3]))
              {
                  list($idColumn, $id) = $this->getUniqueIds($parameters);
                  $query->where('id', '!=', $idColumn);
              }
      
              if($query->count() > 0)
              {
                  return false;
              }
      
              return true;
          }
      
          public function validateDateSame($attribute, $value, $parameters)
          {
              $this->requireParameterCount(1, $parameters, 'date_same');
      
              if ( ! ($date = strtotime($parameters[0])))
              {
                  return strtotime($value) >= strtotime($this->getValue($parameters[0]));
              }
              else
              {
                  return strtotime($value) >= $date;
              }
          }
      
          public function validateDni($attribute, $value, $parameters)
          {
              if(strlen($value)<9) {
                  return false;
              }
      
              $value = strtoupper($value);
      
              $letra = substr($value, -1, 1);
              $numero = substr($value, 0, 8);
      
              // Si es un NIE hay que cambiar la primera letra por 0, 1 ó 2 dependiendo de si es X, Y o Z.
              $numero = str_replace(array('X', 'Y', 'Z'), array(0, 1, 2), $numero);
      
              $modulo = $numero % 23;
              $letras_validas = "TRWAGMYFPDXBNJZSQVHLCKE";
              $letra_correcta = substr($letras_validas, $modulo, 1);
      
              if($letra_correcta!=$letra) {
                  return false;
              }
              else {
                  return true;
              }
          }
      
      }
      

      例如,在 app/routes.php 或其他文件中的解析器验证器之前。

      use Acme\Validators\CustomValidator as CustomValidator;
      
      Validator::resolver(function($translator, $data, $rules, $messages)
      {
          return new CustomValidator($translator, $data, $rules, $messages);
      });
      

      【讨论】:

        猜你喜欢
        • 2020-03-11
        • 2012-11-27
        • 2014-01-28
        • 2015-05-10
        • 1970-01-01
        • 2021-01-12
        • 2014-12-16
        • 1970-01-01
        • 2015-08-13
        相关资源
        最近更新 更多