无法更新CakePHP中的记录

时间:2014-05-22 08:17:15

标签: php mysql cakephp

我的answers表包含字段id player_id read_status

我正在尝试更新read_status

$this->Answer->updateAll(
    array(
        'Answer.' . "'" . $data['field'] . "'" => "'" . trim(base64_decode($data['option'])) . "'"
    ),
    array(
        'Answer.id' => trim(base64_decode($data['id']))
    )
);

以下字段是动态的,来自AJAX请求:

$data['field']包含read_status

$data['option']包含base64编码的yes

$data['id']包含base64编码的id

我得到的错误是:

  

错误:SQLSTATE [42S22]:未找到列:1054未知列'''字段列表中的'Answer.'read_status''   SQL查询:

UPDATE
    `skii`.`answers` AS `Answer`
LEFT JOIN
    `skii`.`players` AS `Player` ON (`Answer`.`player_id` = `Player`.`id`)
SET
    `Answer`.`'read_status'` = 'yes'
WHERE
    `Answer`.`id` = 2
  

注意:如果要自定义此错误消息,请创建app \ View \ Errors \ pdo_error.ctp

3 个答案:

答案 0 :(得分:3)

不要那样做

您正在产生的条件是:

WHERE
    `Answer`.`id` = 2

没有理由为此使用updateAll,updateAll的主要用例是:

  • 更新多条记录
  • not-primary-key更新
  • 更新,例如以原子方式递增计数器

呼叫保存

相反,只需调用saveField:

$this->Answer->id = $id;
$this->Answer->saveField($field, $val);

或保存:

$this->Answer->id = $id;
$this->Answer->save(array($field => $val));

验证您的输入

如果您选择继续使用问题中的代码,请知道它是危险的。

直接向updateAll提供用户输入允许注入任意SQL。确保数据是您期望的数据:

通过updateAll来电,无法阻止某人提交$field

  

“read_status ='yes'AND correct =”

实现这个sql:

SET `Answer`.`read_status` = 'yes' AND correct = 'yes'

永远将用户输入放在CakePHP模型数组的键(更新,条件,顺序)中通常是一个坏主意,因为CakePHP预计密钥不会具有潜在恶意,因此不受应用于值的相同转义逻辑的影响。

因此,转义所有用户输入:

$ds = $this->Answer->getDatsource();

$id = (int)trim(base64_decode($data['id']));
$field = $this->Answer->escapeField((base64_decode($data['field']));
$val = $ds->value(trim(base64_decode($data['option']))), $field);

使用上述逻辑并尝试与第一个示例中所示相同的注入,结果将是:

SET `Answer`.``read_status` = 'yes' AND correct =` = 'yes';

这将失败而不是允许用户随意操纵数据库。

请注意,如果base64编码被添加为“安全”度量,则不会执行任何操作。

答案 1 :(得分:0)

似乎问题是您使用单引号转义字段名称:

  

`Answer`。''read_status'` ='yes'

应该是

  

`回答`.read_status` ='是'

以下更改应解决此问题:

$this->Answer->updateAll(
    array('Answer.' . $data['field'] => trim(base64_decode($data['option']))),
    array('Answer.id' => trim(base64_decode($data['id'])))
);

答案 2 :(得分:0)

试试这个: -

$this->Answer->updateAll(
array(
    'Answer.' . $data['field']  => "'" . trim(base64_decode($data['option'])) . "'"
),
array(
    'Answer.id' => trim(base64_decode($data['id']))
)
);