如何使用yii active record updateall方法

时间:2013-10-09 06:47:17

标签: php yii

如何从活动记录中正确使用updateall方法?安全吗? 我只是使用它:

$rows = $this->updateAll($attributes, 'full_path = :path', array(':path' => $path));

但是在文档http://www.yiiframework.com/doc/api/1.1/CActiveRecord#updateAll-detail中写的内容是什么:

  

更新具有指定条件的记录。有关详细信息,请参阅find()   关于$ condition和$ params的解释。注意,属性不是   检查安全性并且未进行验证。

这是否意味着我们很容易受到sql注入等攻击?我们需要在使用之前调用validate方法吗?如果使用绑定比使用updateAll,使用CDbCommand方法更安全吗? 提前谢谢你的答案。我希望它们会有用。

2 个答案:

答案 0 :(得分:1)

  

这是否意味着我们很容易受到sql注入等攻击?

如果你使用params而不是查询字符串连接,那就不是了 - 这就是params的设计目的。见下面的注释。

  

我们需要在使用之前调用validate方法吗?

由您决定是否需要验证模型属性中的值。

如何在未经验证的情况下使用此示例的一个示例是,您希望以编程方式为多个项目切换布尔值。

  

如果使用绑定,是否使用更安全?

使用params与绑定有些相同 - 它还可以防止SQL注入。


注意:

Yii中的关键字“safe”并不是指防止SQL注入,而是在批量设置/覆盖属性时是否将属性复制到模型中。 E.g:

$model->attributes = $_POST['MyModel'];

在此处阅读更多内容:http://www.yiiframework.com/wiki/161/understanding-safe-validation-rules/

答案 1 :(得分:1)

该方法不容易受到sql injection IF 的影响,您使用第三个参数绑定了参数。

此方法从createUpdateCommand类调用CDbCommandBuilder,此方法将值绑定到预准备语句,因此您不应该容易受到SQL注入攻击

  

没有进行验证。

这意味着它不会根据您在模型中创建的验证规则验证数据。因此,在调用此方法之前,您应该验证来自用户的所有数据是否应该如此(如果存储int,则传递的数据是int,字符串少于255个caracters,...)

由您决定是否要调用validate方法或确保数据正常

  

不检查属性的安全性

这适用于XSS脚本等缺陷,无法控制您存储的文本可能包含某些XSS或其他错误的javascript。

<强>更新

  

属性数组不安全吗?

属性数组是安全的。当您调用updateAll方法时,它将从createUpdateCommand

内部调用CdbCommandBuilder方法

以下是该方法处理params的方法:

foreach($data as $name=>$value)
{
    if(($column=$table->getColumn($name))!==null)
    {
        //Useless code for the example
        $fields[]=$column->rawName.'='.self::PARAM_PREFIX.$i;
        $values[self::PARAM_PREFIX.$i]=$column->typecast($value);
        $i++;
    }
}
//Some useless code for the example
$sql="UPDATE {$table->rawName} SET ".implode(', ',$fields);
$sql=$this->applyJoin($sql,$criteria->join);
$sql=$this->applyCondition($sql,$criteria->condition);
$sql=$this->applyOrder($sql,$criteria->order);
$sql=$this->applyLimit($sql,$criteria->limit,$criteria->offset);

$command=$this->_connection->createCommand($sql);
$this->bindValues($command,array_merge($values,$criteria->params));

正如您所看到的,对每个参数执行类型转换以确保其类型符合预期:$column->typecast($value);

然后它为params调用bindValues方法