PHP 的 PDO : can I prepare a query which will keep unchanged the column if corresponding variable is unset?

标签 php mysql pdo prepared-statement executequery

假设我有一个准备好的查询:

$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]);

我认为这个查询将设置 C 列为 NULL 值(如果这个列可以有 NULL 值,否则它会抛出错误)。

我能否修改 prepareexecute 语句来更改此行为以保持 C 列不变(SET C = C) 如果相应的变量未设置(等于 NULL)?

另一种方法:也许我可以在更新之前获取行,更改所需的列而不是用新值更新?

最佳答案

您所做的是行不通的,您需要绑定(bind)与占位符数量相同的参数。 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));

这会执行语句,其中的占位符和值与现有的一样多;任何 null 值都将被完全忽略。请注意将您的列名列入白名单;这意味着您不应接受任意列名作为用户输入,因为 "`$col` = :$col" 这一步会让您面临 SQL 注入(inject)。至少做这样的事情:

$allowedCols = array('a', 'b', 'c');
if (array_diff_key($_POST, array_flip($allowedCols))) {
    throw new UnexpectedValueException('Received invalid data');
}

关于PHP 的 PDO : can I prepare a query which will keep unchanged the column if corresponding variable is unset?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26872324/

相关文章:

php - Magento - 从数据库手动将订单从 1.4 迁移到 1.7

php - 从对象实例获取php文件

c# - 选择查询不适用于使用 Parameters.AddWithValue 的参数

php - MySQL 连接不工作

php - 如何在php中对curl调用进行单元测试

php - 使用 javascript 发送 POST

php - 我如何连接数据库中的两列,然后根据它选择所有值

PHP PDO MySQL 按日期计算登录连续次数

php - 试图显示数据库表中的每一行,但只显示第一行

php - 仅当尝试使用另一个表时 PDO 无缓冲查询