PDO BindValue不起作用,但可以直接粘贴

时间:2016-09-09 21:53:53

标签: mysql pdo bindvalue

所以我有一些代码

//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

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

1 个答案:

答案 0 :(得分:2)

你不能像这样绑定整个表达式。绑定值不仅仅是字符串替换。您可以在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