zoukankan      html  css  js  c++  java
  • Yii1.1的验证规则

    在Yii1.1的数据验证是由CValidator完成,在CValidator中提供了各种基本的验证规则

    <?php
        public static $builtInValidators=array(
            'required'=>'CRequiredValidator',
            'filter'=>'CFilterValidator',
            'match'=>'CRegularExpressionValidator',
            'email'=>'CEmailValidator',
            'url'=>'CUrlValidator',
            'unique'=>'CUniqueValidator',
            'compare'=>'CCompareValidator',
            'length'=>'CStringValidator',
            'in'=>'CRangeValidator',
            'numerical'=>'CNumberValidator',
            'captcha'=>'CCaptchaValidator',
            'type'=>'CTypeValidator',
            'file'=>'CFileValidator',
            'default'=>'CDefaultValueValidator',
            'exist'=>'CExistValidator',
            'boolean'=>'CBooleanValidator',
            'safe'=>'CSafeValidator',
            'unsafe'=>'CUnsafeValidator',
            'date'=>'CDateValidator',
        );
    ?>

        在Model文件中只需要定义rules方法便可以使用验证规则

      public function rules()
      {
        return array(
          array('bianhao, status', 'required','message'=>'{attribute}为必填项目'),  //bianhao,status是必须的;message:提供错误信息提示
          array('lie, hang, status', 'numerical', 'integerOnly'=>true), //lie,hang,statusbi必须是数字而且必须是整形
          array('bianhao', 'length', 'max'=>10), //bianhao的长度最多是10位
        );
      }

      在验证数据有效性的时候,框架提供给我们的验证规则可能满足不了需求,这时候需要自定义验证规则,在ThinkPhp中我们需要新建一个验证规则文件,这显得就比较麻烦了,那Yii是如何解决这个问题的呢?Yii提供了一个CInlineValidator类来处理这个问题

    <?php
            if(method_exists($object,$name)) //$object当前验证的模型类
            {
                $validator=new CInlineValidator;
                $validator->attributes=$attributes;
                $validator->method=$name;
                if(isset($params['clientValidate']))
                {
                    $validator->clientValidate=$params['clientValidate'];
                    unset($params['clientValidate']);
                }
                $validator->params=$params;
                if(isset($params['skipOnError']))
                    $validator->skipOnError=$params['skipOnError'];
            }
    ?>

     只要在当前的验证模型中存在该验证方法那么就绑定到CInlineValidator类中而在CInlineValidator中我们可以看到

    <?php
        protected function validateAttribute($object,$attribute)
        {
            $method=$this->method;
            $object->$method($attribute,$this->params);
        }
    ?>

    可以看出,在Yii1.1中自定义验证只需要在当前Model中创建就可以了

    <?php
      public function rules()
      {
        return array(
          array('lie,hang',"checkNumber","message"=>"{attribute}的值必须小于10"), //自定义checkNumber方法
        );
      }
    
      /**
       * checkNumber方法 
       * 验证值是否小于10
      */  
      public function checkNumber($attribute,$params=array()){
         if($this->$attribute>10){
             $tihuan['{attribute}']=$this->getAttributeLabel($attribute);
             $this->addError($attribute,strtr($params["message"],$tihuan));
         }
      }
    ?>

    注意:在验证函数中不能直接return必须将错误信息addError

       在验证数据有效性的时候我们必须还需要考虑场景的问题,不同的场景需要提供不同的验证规则,这点在ThinkPHP5中已经讨论过,Tp5的解决方案是比较繁琐而且不灵活的,那在Yii1.1中是怎么解决的呢?

       Yii1.1的CVaildate提供了"on"属性和"except"属性,而在CActiveRecord中初始化中我们可以看到

        public function __construct($scenario='insert')
        {
            if($scenario===null) // internally used by populateRecord() and model()
                return;
    
            $this->setScenario($scenario);  //我们先看这个这是表示为模型设置一个应用场景
            $this->setIsNewRecord(true);
            $this->_attributes=$this->getMetaData()->attributeDefaults;
    
            $this->init();
    
            $this->attachBehaviors($this->behaviors());
            $this->afterConstruct();
        }

     在CActiveRecord初始化时我们就需要为该模型设置一个应用场景,默认应用场景为"insert"。再来看CModel中是如何获取当前需要验证的Vaildator集合的

     1     public function getValidators($attribute=null)
     2     {
     3         if($this->_validators===null)
     4             $this->_validators=$this->createValidators();
     5         $validators=array();
     6         $scenario=$this->getScenario();
     7         foreach($this->_validators as $validator)
     8         {
     9             if($validator->applyTo($scenario))  
    10             {
    11                 if($attribute===null || in_array($attribute,$validator->attributes,true))
    12                     $validators[]=$validator;
    13             }
    14         }
    15         return $validators;
    16     }

    代码3-4行:获取当前所有验证规则

    代码6行:获取当前模型验证规则

    代码7-14行:在这个foreach循环里筛选符合当前场景的集合,我们看下$validator->applyTo($scenario) 在CValidator中

    1     public function applyTo($scenario)
    2     {
    3         if(isset($this->except[$scenario]))
    4             return false;
    5         return empty($this->on) || isset($this->on[$scenario]);
    6     }

    代码3-4行:当前场景是否在$this->except中如果在则除掉该验证规则

    代码5行:当前验证规则如果没有on属性则保留该验证规则,如果有on属性并且当前场景在$this->on中则保留该规则如果不在则去除

    到这,能发现在CValidator中"on"表示该验证规则属于哪个场景(scenario),如果没有"on"属性则该验证规则属于任何场景,如果有"on"属性的话则该验证规则只能属于该on属性下的验证规则;而"except"则恰恰相反,设置了"except"属性就表示该验证规则一定不属于"except"下的场景

    看下简单的例子

    1   public function rules()
    2   {
    3     return array(
    4       array('lie,hang',"checkNumber","message"=>"{attribute}的值必须小于10","on"=>"update,insert"),
    5       array('bianhao, status', 'required',"message"=>'{attribute}为必填项目',"except"=>"insert"),
    6       array('lie, hang, status', 'numerical', 'integerOnly'=>true),
    7       array('bianhao', 'length', 'max'=>10),
    8     );
    9   }

    代码4行:该验证规则只能属于update,insert下两个应用场景

    代码5行:该验证规则不属于insert应用场景

    代码6-7行:该验证规则属于任何应用场景

    想要使用不同场景该怎么办?很简单只需要初始化的时候指定场景就好了 $model=new Model($scenario),如果想改变场景怎么办?直接调用$model->setScenario(scenario)就可以了。

    总结:对比下与Tp5的验证规则,Yii1.1的显得更加简洁轻便,对不同场景的调用也更加灵活,自定义验证方法也只需要在Model本身添加自定义函数即可。

    ps:Yii1.1还提供了前端JS的数据验证方法,但是我表示不太喜欢在PHP中写前端的JS代码,分开一点不是更好么 

  • 相关阅读:
    如何将asp.net MVC2项目升级为MVC3项目(微软官方自动升级工具:ASP.NET MVC 3 Application Upgrader )
    扩展Html Helper类,ASP.NET MVC框架提供了一个帮助我们构造Html元素的类:TagBuilder
    详解ASP.NET MVC2项目升级到MVC 3 RC
    NHibernate学习
    ASP.MVCNOTE
    MVC问题反馈页面代码
    Silverlightnote
    jqGrid
    必须掌握的八个DOS命令
    分页且带条件的存储过程
  • 原文地址:https://www.cnblogs.com/panyangfeng/p/6251648.html
Copyright © 2011-2022 走看看