设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 数据 创业者 手机
当前位置: 首页 > 站长学院 > PHP教程 > 正文

Laravel参数验证学习中有什么常见问题

发布时间:2022-06-30 13:31 所属栏目:121 来源:互联网
导读:今天这篇我们来学习和了解Laravel参数验证学习中有哪些常见问题,下文的讲解详细,步骤过程清晰,对大家进一步学习和理解Laravel参数验证学习中有哪些常见问题有一定的帮助。有这方面学习需要的朋友就继续往下看吧! 验证器怎么创建的,谁创建的 Laravel 文
  今天这篇我们来学习和了解“Laravel参数验证学习中有哪些常见问题”,下文的讲解详细,步骤过程清晰,对大家进一步学习和理解“Laravel参数验证学习中有哪些常见问题”有一定的帮助。有这方面学习需要的朋友就继续往下看吧!
 
     验证器怎么创建的,谁创建的
 
  Laravel 文档调用验证器,除了通过控制器,还有就是通过Facades的方式创建验证器对象。Validator::make($data,$rule,$message)。
 
  如果需要自定义验证器类(比如我需要把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;
  });
  //\Illuminate\Contracts\Validation\Factory 源码
  public function extend($rule, $extension, $message = null)
  {
    $this->extensions[$rule] = $extension;
 
    if ($message) {
      $this->fallbackMessages[Str::snake($rule)] = $message;
    }
  }
  //\Illuminate\Validation\Validator 源码
  protected function callExtension($rule, $parameters)
  {
    $callback = $this->extensions[$rule];
 
    if (is_callable($callback)) {
      return call_user_func_array($callback, $parameters);
    } elseif (is_string($callback)) {
      return $this->callClassBasedExtension($callback, $parameters);
    }
  }
 
  protected function validateAttribute($attribute, $rule)
  {
    ...
    $method = "validate{$rule}";
    if ($validatable && ! $this->$method($attribute, $value, $parameters, $this)) {
      $this->addFailure($attribute, $rule, $parameters);
    }
  }
 
  public function __call($method, $parameters)
  {
    $rule = Str::snake(substr($method, 8));
 
    if (isset($this->extensions[$rule])) {
      return $this->callExtension($rule, $parameters);
    }
 
    throw new BadMethodCallException(sprintf(
      'Method %s::%s does not exist.', static::class, $method
    ));
  }
  Factory提供了extend方法用于扩展规则验证方法。所有的扩展规则最终都会被传到验证器中。验证器在验证参数的过程中,如果找到匹配的验证规则,则直接进行验证。否则调用魔术方法__call查找扩展验证函数。扩展函数返回布尔值,返回true则表示验证通过,返回false表示验证失败。
 
  2 通过自定义规则类扩展
  Laravel 中提供了Illuminate\Contracts\Validation\Rule接口,只有实现了这个接口的类都认为是符合的自定义验证规则类。
 
  <?php
 
  namespace Illuminate\Contracts\Validation;
 
  interface Rule
  {
    /**
     * Determine if the validation rule passes.
     *
     * @param string $attribute
     * @param mixed $value
     * @return bool
     */
    public function passes($attribute, $value);
 
    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message();
  }
  自定义规则类需要实现的方法有passes方法,用于验证参数是否合法。message方法,用于提供验证失败的错误提示信息。
 
  使用自定义验证类,相对于extend方法扩展有一个很大的bug就是无法在自定义类中获取到当期的验证器对象。从而导致在当前扩展的验证规则中,只能过获取到需要验证的数据,而获取不到其他的字段数据,无法进行联合字段的验证。像上面比较两个字段的大小的验证规则就无法实现。
 
  如果想要通过自定义验证规则类实现上面两个字段大小比较的验证规则,则需要自定义验证类,修改validateUsingCustomRule方法,将当期验证器传入到自定义验证规则实例对象中去。
 
  protected function validateUsingCustomRule($attribute, $value, $rule)
  {
    if(method_exists($rule, 'setValidator'))
    {
      $rule->setValidator($this);
    }
    return parent::validateUsingCustomRule($attribute,$value,$rule);
  }
  如何实现用当期类方法作为验证规则验证函数
  像Yii2中,因为基本上所有的对象都有验证方法,所以很容易用当期类方法作为验证规则验证函数。
 
  例如,一个验证规则如下,表示用当期类的validateMinNum对参数进行验证,那么,这样的一个功能,如何在Laravel中实现呢。
 
  ['min_num'=>'validateMinNum']
  方法1 通过自定义类实现 Laravel提供了ClosureValidationRule自定义验证类,用来添加回调函数的验证。
  例如
 
  $rule = [
    'min'=>new ClosureValidationRule([$this,'checkv'])
  ];
  $data = ['min'=>10];
  $v = Validator::make($data,$rule);
  方法2 通过extend方式实现
  $rule = [
    'min'=>'checkv'
  ];
  Validator::extend('checkv',[$this,'checkv']);
  但是这种方式对验证器的影响是全局的。不建议使用。
 
  总结
  通过以上源码的学习,可以看出Laravel验证器的创建都是用过验证器工厂类创建的。如果需要自定义验证器,可以通过修改验证器工厂类,或者设置验证器工厂类的resolver属性接管验证器的实例化。
 
  验证规则的扩展有两种方式,一种是通过extend方式实现。extend方式对验证器的影响是全局的,整个运行进程有效。可以获取到验证器本身,因此可以做多个字段关系的验证;另一种是通过自定义规则类实现。自定义规则了只对使用自定义规则类的验证有效。但是自定义规则类本身无法直接获取到验证器本身,不能够做多个字段关系的验证。如果需要实现,则需要使用自定义验证器,将验证器传入到验证规则中去。
 
  Laravel本身提供了ClosureValidationRule的验证规则用于处理回调函数验证规则。同时也可以使用extend方式进行回调函数的验证。
 
  上述内容具有一定的借鉴价值,感兴趣的朋友可以参考,希望能对大家有帮助。

(编辑:ASP站长网)

    网友评论
    推荐文章
      热点阅读