覆盖yii中重复的验证规则

时间:2013-01-27 18:27:21

标签: php yii

PLZ我有一些规则功能,我不想在其代码中更改(BaseModel from database) 并且我在模型中使其他规则起作用,我想改变它

基地一个“不要改变”

public function rules() {
        return array(
            array('start_date, end_date, info, type_id', 'required'),

            array('start_date, end_date, type_id', 'length', 'max'=>10),

    }

我希望更改继承自基本模型的模型中的其他函数 这是它的代码

public function rules()
    {
        $rules = array(
                    array('start_date, end_date, type_id', 'length', 'max'=>16),
        );
        return array_merge($rules,parent::rules());

    }

它使用最大值为10而不是16的问题 我想要它16 即使我最后一行改为

    return array_merge(parent::rules(),$rules);

3 个答案:

答案 0 :(得分:0)

它可能无效的原因是'max'=>10的{​​{1}}规则仍然存在于rules()中,而与订单无关。替换规则对我有用。

public function rules(){
    $rules=parent::rules();
    $rules[1]=array('start_date, end_date, type_id', 'length', 'max'=>16);
    return $rules;
}

修改

要使用'start_date, end_date, type_id'替换规则作为“密钥”,您需要递归array search

public function rules(){
    $rules=parent::rules();
    $index=0;//index of the rule
    outer: foreach($rules as $rule){
        if(array_search('start_date, end_date, type_id',$rule)!==false)
             break outer;
        $index++;
    }
    $rules[$index]=array('start_date, end_date, type_id', 'length', 'max'=>16);
    return $rules;
}

这将检查现有规则,如果不存在,则将规则添加为$rules的最后一个元素。如果有人编辑基类中的第一个元素,例如向规则添加新的属性/字段,这将不起作用。

答案 1 :(得分:0)

刚刚完成相同的任务,创建了一个合并辅助函数:

public function mergeRules($parent, $rules)
{
    // creating curent rules map
    $rulesMap = [];
    foreach ($rules as $rule) {
        $validator = $rule[1];
        $attributes = array_map('trim', explode(',', $rule[0]));
        if (!isset($rulesMap[$validator])) {
            $rulesMap[$validator] = [];
        }
        $rulesMap[$validator] = CMap::mergeArray($rulesMap[$validator], $attributes);
    }

    // checking for attributes in parent rules against created rule map
    if (!empty($rulesMap)) {
        foreach ($parent as $i => $rule) {
            $validator = $rule[1];
            if (empty($rulesMap[$validator])) {
                continue;
            }
            $attributes = array_map('trim', explode(',', $rule[0]));
            foreach ($attributes as $k => $attribute) {
                if (in_array($attribute, $rulesMap[$validator])) {
                    unset($attributes[$k]);
                }
            }
            // unset if we got inherited rule of same validator
            if (empty($attributes)) {
                unset($parent[$i]);
            } else {
                $parent[$i][0] = implode(', ', $attributes);
            }
        }
    }

    return array_merge($parent, $rules);
}

然后在rules()函数中调用:

public function rules()
{
    // NOTE: you should only define rules for those attributes that
    // will receive user inputs.

    $rules = array(
        blablabla...
    );

    return $this->mergeRules(parent::rules(), $rules);

}

答案 2 :(得分:0)

做到这一点的一种方法是给你的规则一个键。

来自docs

Note: It is handy to give names to rules i.e.

public function rules()
{
    return [
        // ...
        'password' => [['password'], 'string', 'max' => 60],
    ];
}

You can use it in a child model:

public function rules()
{
    $rules = parent::rules();
    unset($rules['password']);
    return $rules;
}

在您的情况下,您可以在父类中执行此操作:-

public function rules() {
        return array(
            'requiredArray' => array('start_date, end_date, info, type_id', 'required'),

            'maxLengthArray' => array('start_date, end_date, type_id', 'length', 'max'=>10),

    }

在您的孩子班级中:-

public function rules()
{
    $parent = parent::rules();
    $rules = array(
        'maxLengthArray' => array('start_date, end_date, type_id', 'length', 'max'=>16)
    );
    unset($parent['maxLengthArray']);
    
    return array_merge($parent,$rules);

}

编辑:

请记住,如果您只想更新 'maxLengthArray' 中的 'one' 属性......其他属性必须在从父级(显然 :) 'unset' 后重新应用)。

例如:- 仅更改 type_id 长度...孩子看起来像:-

public function rules()
{
    $parent = parent::rules();
    $rules = array(
        'maxLengthArray' => array('start_date, end_date', 'length', 'max'=>10),
        'typeIdLength' => array('type_id', 'length', 'max'=>16),

    );
    unset($parent['maxLengthArray']);

    return array_merge($parent,$rules);

}