2012-01-07 4 views
0

Я получаю очень неприятные результаты при попытке привязать параметры к подготовленному заявлению PDO.PHP PDO BindParam/BindValue Double Quote Bug

В результате возникает эта ошибка: У вас возникла ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с '' элементами '' по строке 1

Ошибка ясно показывает, что в табличных «элементах» указаны одинарные кавычки, t be. Я собрал немного теста ниже. Как вы можете видеть, я не ставил параметры в кавычки в инструкции, чтобы начать, что, вероятно, было бы предположением большинства людей. Я знаю, что это имеет какое-то отношение к функции BindParam/BindValue (я пробовал оба с одинаковыми результатами), потому что если вы обойдете функцию bindParams, установив $ params в null и заменив «table» на «items» в инструкции, он работает отлично.

<?php 

echo 'started test...'; 

//connect to database 

try { 
    $dbHandle = new PDO('mysql:dbname=mydatabase;host=mysql.mywebsite.com', 'myuser', 'mypass'); 
} catch (PDOException $e) { 
    echo 'Database connection failed: ' . $e->getMessage();  
} 

//print out the contents of table 'items' 

print_r(query("SELECT * FROM :table", array("table" => "items"), $dbHandle)); 

//the query() function used above 

function query($query_str, $params = null, $dbHandle) { 

    $stmt_obj = $dbHandle->prepare($query_str); 

    if($params != null) {   
     bindParams($stmt_obj, $params); 
    } 

    $stmt_obj->execute(); 

    //debug stuff 
    echo '<pre>'; 
    echo 'ERROR: '; 
    $error = $stmt_obj->errorInfo();   
    echo $error[2].'<br /><br />'; 
    echo 'DEBUG DUMP:<br />'; 
    $stmt_obj->debugDumpParams(); 
    echo '</pre>'; 

    if (preg_match("/SELECT/i", $query_str)) { 
     $result = array();  
     while ($row = $stmt_obj->fetch(PDO::FETCH_ASSOC)) {   
      array_push($result, $row); 
     } 
     unset($stmt_obj); 
     return $result; 
    } 

} 

function bindParams($stmt, $params) { 
    if(is_object($stmt) && ($stmt instanceof PDOStatement)) 
    {   
     foreach($params as $key => $value) 
     {    
      if(is_int($value)) { 
       $param = PDO::PARAM_INT; 
      } elseif(is_bool($value)) { 
       $param = PDO::PARAM_BOOL; 
      } elseif(is_null($value)) { 
       $param = PDO::PARAM_NULL; 
      } elseif(is_string($value)) { 
       $param = PDO::PARAM_STR; 
      } else { 
       $param = FALSE; 
      } 
      if($param) {               
       $stmt->bindValue(":$key", $value, $param);     
      } 
     } 
    } 

Кто-нибудь хочет вывести меня из моих страданий и указать на что-то действительно очевидное, что мне не хватает?

ответ

0

Символы в подготовленных операторах являются только заполнителями для значений, а не идентификаторов, поэтому вы не можете создать подготовленный оператор с динамическим столбцом или именем таблицы. Все ссылки на базы данных должны быть разрешены во время подготовки. Даже если это неверно, как PDO/MySQL знает, должен ли заполнитель :table быть буквальным или идентификатором? У них разные правила цитирования.

Это ограничение является общим для подготовленных операторов во всех системах баз данных и всех API. Это, конечно, не ошибка PDO.

+0

Ах, а это очевидное, что мне нужно было услышать! Ура! – Paul