假设我有一个准备好的查询:
$update_rq = $DB->prepare("
UPDATE `table`
SET
`A` = :a,
`B` = :b,
`C` = :c
WHERE `id` = :id
LIMIT 1
");
如果我将使用以下代码执行此查询:
$update_rq->execute(['id' => $id,'a' => 1,'b' => 2]);
我认为这个查询会用NULL
值设置C
列(如果这个列可以有NULL值,或者如果不能,它会抛出一个错误)。
如果相应的变量未设置(等于NULL),我可以修改prepare
或execute
语句来更改此行为以保持C
列不变(SET C = C
)吗?
另一种方法:也许我可以在更新之前获取行,更改所需列,然后用新值更新?
您所做的不会起作用,您需要绑定与占位符数量相同的参数。PHP不会隐式地替换null
,它只会失败。你可以做一些简单的事情,比如:
$data = array('a' => 1, 'b' => 2, 'c' => null);
$data = array_filter($data);
$placeholders = array_map(function ($col) { return "`$col` = :$col"; }, array_keys($data));
$query = sprintf('UPDATE `table` SET %s WHERE id = :id', join(', ', $placeholders));
$stmt = $DB->prepare($query);
$stmt->execute($data + array('id' => $id));
这将使用尽可能多的占位符和值来执行语句;则完全忽略任何CCD_ 8值。请注意将您的列名列入白名单;这意味着您不应该接受任意列名作为用户输入,因为"`$col` = :$col"
步骤将打开SQL注入。至少做一些类似的事情:
$allowedCols = array('a', 'b', 'c');
if (array_diff_key($_POST, array_flip($allowedCols))) {
throw new UnexpectedValueException('Received invalid data');
}