关于使用Yii框架开发时数据库增加字段后保存无效的问题

在dev过程中难免要变动数据库的字段, 这时候如果在Yii的Model文件不做处理的话,Yii框架是不会使用默认添加新字段来保存提交内容的。所以按下面步骤来操作:

1、在rules()方法里写入添加字段的验证规则
2、如果用到search方法的话写入search规则
3、如果此字段在前台展示的话写入attributelabels属性

这样就可以来实现对新字段的CREATE和UPDATE操作了。

下面就是原理的分析了:
ok
我们一般使用Create的方法的话这一句是不会少的“$model->attributes = $_POST['User']”, 这一句其实在Yii框架的内部是调用了一个Setter的方法,即“setAttributes()”, 可以在手册的Cmodel类里找着;下面贴出来这个setter的代码来分析下

public function setAttributes($values,$safeOnly=true)
{
    //如果给定的setter值不为数组的话无效赋值
    if(!is_array($values))
        return;
 
    //通过$safeOnly来判定返回的attributes
    $attributes=array_flip($safeOnly ? $this->getSafeAttributeNames() : $this->attributeNames());
     
    //赋值啦, 还用解释么?
    foreach($values as $name=>$value)
    {
        if(isset($attributes[$name]))
            $this->$name=$value;
        else if($safeOnly)
            $this->onUnsafeAttribute($name,$value);
    }
}

在这段代码的话你可以着重看下中间部分的那个三元运算符逻辑。
这里的$safeOnly参数默认是true所以会调用到getSafeAttributeNames()方法。OK, 再看下这个方法的代码吧

public function getSafeAttributeNames()
{
    $attributes=array();
    $unsafe=array();
 
    foreach($this->getValidators() as $validator)
    {
        //判定验证器里的元素是不是安全?
        //关于安全的说明在代码后面。
        if(!$validator->safe)
        {
            foreach($validator->attributes as $name)
                $unsafe[]=$name;
        }
        else
        {
            foreach($validator->attributes as $name)
                $attributes[$name]=true;
        }
    }
 
    //重点看这人, 会把所有不安全的方法都Unset掉的。
    foreach($unsafe as $name)
        unset($attributes[$name]);
    return array_keys($attributes);
}

A safe attribute is one that is associated with a validation rule in the current scenario.
注意下这句话, 是对safe属性的一个说明:一个安全的属性就是与当前的scenario关联的一个属性较验。翻译的不怎么滴,意思就是要写进rules方法里并且要关联一个validator , 这样明白了吧。:)

好了,到这里明白为什么字段加上了但是Post也可以抓包到值的提交,但就是数据不入库的原因了吧。从这一点来看, Yii为安全做的想法很多了, 当然你不想使用Yii的这一套判定的话直接来这个吧

//把safeOnly关掉就可以咯。
$model->setAttributes($_POST['User'], false);

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?