2016-09-09 18 views
1

Поэтому у меня есть некоторый код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' то он работает отлично. Как только я попытаюсь связать его с помощью:: или с помощью ?, тогда он терпит неудачу. Я не знаю, что с этим делать :(Спасибо за помощь!

+0

Знаете ли вы разницу между ** выражением ** и ** значением **? Вы можете привязывать только значения. Ничего больше. Нет имен таблиц, нет имен столбцов, нет произвольно построенного динамического SQL. Это так тривиально, что это путает людей. Идея заключается в том, что вы обеспечиваете хороший SQL, который работает, тогда вы говорите MySQL «эй, здесь я хочу значения», тогда вы помещаете хорошие заполнители в форме ': param_name', а MySQL обязывает, обрабатывает значение как string/int и фиксирует все предмет на диск. Кроме того, знаете ли вы о композиторах и метрических тоннах библиотек, которые помогут вам забыть о том, как это сделать вручную? –

+0

Спасибо за ответы, полностью очищенные сейчас :) никаких выражений, которые я должен был реализовать ха-ха. Спасибо за разъяснения! – MisterQuacker

+0

Ну, я рад, что помог. Теперь пойдите, постройте что-то удивительное :) –

ответ

2

Вы не можете привязывать целые выражения как это. Значения привязки - это не просто подстановка строк. Вы можете связать значение в запросе SQL только где вы обычно ставите одно скалярное значение. Если вам нужны два значения, например, для предиката BETWEEN, вам нужны два заполнителя.

Кроме того, вы не должны ставить кавычки в свои значения. То, что заполнитель означает точно одно скалярное значение делает ненужным цитаты.

Похоже, вы пытаетесь сделать функцию общего назначения, чтобы вы могли сделать любой c которые вы хотите, и ваш массив $clause должен содержать столбец, оператор и значение.

Вы собираетесь должен написать код для форматирования SQL-разному для многозначных предикатов как IN() или BETWEEN:

$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.