PHP PDO BindParam/BindValue Двойная кавычка

Я получаю очень разочаровывающие результаты, когда пытаюсь связать параметры с подготовленным оператором PDO.

Результатом является эта ошибка: у вас есть ошибка в вашем синтаксисе SQL; проверьте руководство, соответствующее вашей версии сервера MySQL, чтобы найти правильный синтаксис для использования рядом с '' items '' в строке 1

Ошибка ясно показывает, что таблица "items" заключена в одинарные кавычки, а это не должно быть. Я собрал небольшой тест ниже. Как вы можете видеть, я не помещаю параметры в кавычки в утверждении для начала, что, вероятно, было бы первоначальным предположением большинства людей. Я знаю, что это как-то связано с функцией 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);                  
            }
        }
    }

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

1 ответ

Решение

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

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

Другие вопросы по тегам