Yii2.0中model的validator生成和运行浅析

来源:互联网 发布:电信网络诈骗例子 编辑:程序博客网 时间:2024/06/05 11:17

1.使用方式

在rules中为每个字段配置验证器,在使用$model->validate()或$model->save()时,触发验证$model->save()最终也是调用$model->validate()方法

2.$model->validate()方法解析

//根据rules验证各个字段public function validate($attributeNames = null, $clearErrors = true){    ...    $scenarios = $this->scenarios();//获取场景数组,在这个过程中各个验证器对象会被创建出来,并保存到一个数组中    ...    foreach ($this->getActiveValidators() as $validator) {//获取验证器,在保存验证器的数组中取出,或根据rules直接生成验证器        $validator->validateAttributes($this, $attributeNames);//调用各个验证器的validateAttributes方法,进行验证    }    ...}//获取场景的方法public function scenarios(){    ...    $this->getValidators();//其中有获取验证器对象的方法    ...}//获取有效的验证器对象public function getActiveValidators($attribute = null){    $validators = [];    $scenario = $this->getScenario();    foreach ($this->getValidators() as $validator) {        if ($validator->isActive($scenario) && ($attribute === null || in_array($attribute, $validator->attributes, true))) {        $validators[] = $validator;        }    }    return $validators;}//获取所有验证器对象public function getValidators(){    if ($this->_validators === null) {        $this->_validators = $this->createValidators();    }    return $this->_validators;}//创建验证器public function createValidators(){    $validators = new ArrayObject;    foreach ($this->rules() as $rule) {//需要遍历rules方法返回的数组        if ($rule instanceof Validator) {            $validators->append($rule);//如果是验证器对象,直接添加        } elseif (is_array($rule) && isset($rule[0], $rule[1])) { // attributes, validator type            $validator = Validator::createValidator($rule[1], $this, (array) $rule[0], array_slice($rule, 2));//创建验证器对象:第2个参数为验证器名,第一个参数为字段名,剩余的参数作为数组参数传递            $validators->append($validator);        } else {            throw new InvalidConfigException('Invalid validation rule: a rule must specify both attribute names and validator type.');        }    }    return $validators;}//真正的创建对象方法1).rules中的第2个参数是匿名函数或自定义的model中的一个方法创建InlineValidator对象,此对象的method属性是匿名函数或model中自定义的验证方法剩余的参数,键名作为对象的属性名,值作为此属性的值2).rules中的第2个参数是yii框架validator内置的验证器创建对应的内置验证器对象剩余的参数,键名作为对象的属性名,值作为此属性的值public static function createValidator($type, $model, $attributes, $params = []){    $params['attributes'] = $attributes;    if ($type instanceof \Closure || $model->hasMethod($type)) {//如果是匿名函数,或此model中有自定义的验证方法,则作为InlineValidator的method属性传递进去        // method-based validator        $params['class'] = __NAMESPACE__ . '\InlineValidator';        $params['method'] = $type;    } else {        if (isset(static::$builtInValidators[$type])) {//可能是使用的yii框架已经实现的一些验证方法            $type = static::$builtInValidators[$type];        }        if (is_array($type)) {            $params = array_merge($type, $params);        } else {            $params['class'] = $type;        }    }    return Yii::createObject($params);}

个人博客链接:http://www.tanklh.cc/typecho/index.php/archives/6/