PDO 更新准备好的语句不起作用

PDO update prepared statement not working

pdo-bindparam-into-one-statement

我是 PDO 的新手,我想我迷路了.. 我想要的是使用相同的变量来插入和更新两者..

 function pdoSet($fields, &$values, $source = array()){
    $set = '';
    $values = array();
    if(!$source) $source = &$_POST;
    foreach($fields as $field){
        if(isset($source[$field])){
            $set .= " $field =:$field, ";
            $values[$field] = $source[$field];
        }
    }
    return substr($set, 0, -2);
}

$fields = array(
    'name'
    , 'part'
    , 'tel'
    , 'email'
    , 'title'
    , 'contents'
);

if(!$idx){
    $fields[] = 'reg_date';
    $values[] = 'now()';
    $st = $pdo -> prepare("insert into qna_board set ".pdoSet($fields, $values));
}else{
    $st = $pdo -> prepare("update qna_board set ".pdoSet($fields, $values)." where idx = :idx");
    $st ->bindParam(':idx', $idx);
}

$st->execute($values);

插入成功,更新失败。 当我使用 $idx 而不是 :idx 时它起作用了.. 你能告诉我问题是什么吗?

您可以 bind 参数 将它们传递给 execute。您不能同时执行这两项操作,当您将任何参数传递给 execute 时,PDO 将丢弃任何绑定参数。因此,您的 idx 在执行查询时不受约束。最简单的修复:

$st->execute($values + compact('idx'));

通过接受来自 $_POST 顺便说一句的原始字段名称,您正在向旧的 SQL 注入敞开心扉。

此外,顺便说一句:

join(', ', array_map(
    function ($field) { return "`$field` = :$field"; },
    $fields
))

.= '.., 'substr更加理智。

您现在收到的查询是什么?这样我们就可以更好的看到哪里出了问题。

你应该小心,在准备好的语句中只使用 $_POST 作为 $source。有人可以将 SQL 注入您的查询。始终清理查询的输入。

在 pdoSet 中,您正在清除函数参数 $values,因为这是通过引用 (&$values) 给出的,您在代码的其余部分引入了副作用。