将PDO准备的语句与MySQL查询变量一起使用

时间:2019-02-21 18:50:23

标签: php mysql pdo

我正在尝试使用PHP PDO增加表中的行,而我想出了这个查询

UPDATE users SET log = ? 

我正在尝试根据日志各列上的先前值进行更新

所以,如果我的桌子以前是这样的

+----+------+------+-----------+--------+ | id | name | age | eye_color | log | +----+------+------+-----------+--------+ | 21 | OLa | 19 | black | 1 | | 22 | OLa | 19 | Green | 2 | | 23 | OLa | 19 | Grey | 3 | +----+------+------+-----------+--------+

我期望得到这个结果

+----+------+------+-----------+--------+ | id | name | age | eye_color | log | +----+------+------+-----------+--------+ | 21 | OLa | 19 | black | 2 | | 22 | OLa | 19 | Green | 3 | | 23 | OLa | 19 | Grey | 4 | +----+------+------+-----------+--------+

我发现我可以使占位符的价值成为

log + 1

进行完整查询

UPDATE users SET log = log + 1

这在我使用PDO的查询方法时也很好,而且在我的终端上也很好,当我尝试使用准备好的语句更新它时,问题就来了,如果我这样做了

$stmt = $this->pdo->prepare("UPDATE users SET log = ?");
$stml->execute(['height + 1']);

然后所有日志列变为0。

有什么地方做错了吗?我也知道我可以使查询简单

$stmt = $this->pdo->prepare("UPDATE users SET log = log + 1");
$stmt->execute(['log + 1']);

但是我更喜欢最初的方法,因为我遇到了一些限制。

2 个答案:

答案 0 :(得分:2)

由于您没有从用户那里获得信息,并且将1加到一列中,所以您可以安全地执行常规查询。

UPDATE users SET log = log + 1

如果使用prepare语句,则必须查询该列以获取当前值,然后在第二个查询中执行更新并将其添加1。

答案 1 :(得分:2)

您不能使用查询参数在语法中插入表达式。参数不只是字符串插值。如果是这样,使用它们将没有任何好处,因为您已经可以在PHP中轻松进行字符串插值。

查询参数的全部要点是该值与服务器上的查询组合在一起,在之后解析了SQL语法,因此插入任何新语法为时已晚,例如表达式。

查询参数始终被视为单个标量值。您不能将参数用于:

  • 表标识符
  • 列标识符
  • SQL关键字
  • 表情
  • 值列表

正如其他人所解释的那样,在这种情况下,您仍然无需使用查询参数。在查询中直接使用文字表达式log + 1是安全的。没有任何不可信的内容(来自用户或其他来源)被插入到查询中,因此没有SQL注入的风险。