【问题标题】:PDO BindValue doesn't work but works with direct pastePDO BindValue 不起作用,但适用于直接粘贴
【发布时间】:2017-01-18 02:45:50
【问题描述】:

所以我有一些代码

//passed as function param
$clause[2] = "'2016-09-09' AND '2016-09-09'"

$sql = "SELECT {$columns} FROM `{$table}` WHERE `{$clause[0]}` {$clause[1]} :clause";
$stm = $this->db->prepare($sql);
$stm->bindValue("clause", $clause[2]);
if ($stm->execute()) {
   return $stm->fetchAll(PDO::FETCH_OBJ);
}
d
//echo'd $sql
SELECT * FROM `deliveries` WHERE `delivery-date` BETWEEN :clause

如果我将$sql 中的:clause 替换为原始输入'2016-09-09' AND '2016-09-09',那么它可以正常工作。一旦我尝试使用 :clause 或使用 ? 绑定它,它就会失败。我不知道该怎么办:(谢谢你的帮助!

【问题讨论】:

  • 你知道表达式的区别吗?您只能绑定值。没有其他的。没有表名,没有列名,没有一些随机构造的动态 SQL。它是如此微不足道,以至于使人们感到困惑。这个想法是你提供了很好的 SQL,然后你告诉 MySQL “嘿,我想要值”,然后你以 :param_name 的形式放置很好的占位符,MySQL 强制,将值视为 string / int 并粘贴整个东西到磁盘。另外,您是否知道 composer 和大量的库可以帮助您忘记手动执行此 PDO 的事情?
  • 感谢您的回复,现在完全清楚了:) 没有我应该意识到的表达哈哈。感谢您的澄清!
  • 嗯,很高兴我能帮上忙。现在去构建一些很棒的东西:)

标签: mysql pdo bindvalue


【解决方案1】:

你不能像那样绑定整个表达式。绑定值不仅仅是字符串替换。您可以在通常放置单个标量值的 SQL 查询中绑定值。如果您需要两个值,例如 BETWEEN 谓词,则需要两个占位符。

此外,您不得在绑定值中加上引号。占位符仅表示一个标量值这一事实使得引号变得不必要。

看起来您正在尝试创建一个通用函数,以便您可以创建任何您想要的条件,并且您的 $clause 数组应该包含列、运算符和值。

您将不得不编写代码来为IN()BETWEEN 等多值谓词设置不同的SQL 格式:

$column = $clause[0];
$operator = $clause[1];
$valuesArray = (array) $clause[2];
switch ($operator) {
case 'IN':
    $expression = "(" . implode(",", array_fill(1, count($valuesArray), "?") . ")";
    break;
case 'BETWEEN':
    $expression = "? AND ?";
    break;
default:
    $expression = "?";
}
$sql = "SELECT {$columns} FROM `{$table}` WHERE `{$column}` {$operator} {$expression}";
$stm = $this->db->prepare($sql);
$stm->execute($valuesArray);
return $stm->fetchAll(PDO::FETCH_OBJ);

我懒得测试execute()的返回值,因为你应该只启用PDO::ERRMODE_EXCEPTION

【讨论】:

    猜你喜欢
    • 2013-01-03
    • 2011-02-11
    • 1970-01-01
    • 2017-07-13
    • 2016-01-28
    • 2015-06-10
    • 2014-01-14
    • 2014-03-18
    相关资源
    最近更新 更多