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

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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值