Yii1.1的验证规则

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

<?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类来处理这个问题app

<?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必须将错误信息addErrorui

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

   Yii1.1的CVaildate提供了"on"属性和"except"属性,而在CActiveRecord中初始化中咱们能够看到url

    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集合的spa

 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行:获取当前全部验证规则code

代码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代码,分开一点不是更好么 

相关文章
相关标签/搜索