PHP PDO - имя таблицы привязки?

Можно ли связать имя таблицы?

Я хочу, чтобы класс читал столбцы из таблиц и, в зависимости от типа поля, генерировал для меня входные данные формы. Когда я делаю $form = new form("users");, конструктор должен начинать с получения имен полей из таблицы со следующим кодом:

class form{

    public function __construct($table, $skip = array("id")){
        $pdo = new PDO('mysql:host=localhost;dbname=site;',USER,PASS);

        $query = $pdo->prepare("DESCRIBE :table");

        $query->bindValue(':table', $table, PDO::PARAM_STR, strlen($table));

        $query->execute();

        while($field = $query->fetch(PDO::FETCH_NUM)){
            var_dump($field);
            echo "<br /><br />";
        }

        unset($pdo);
    }
}

Это работает отлично, когда я указываю "users" вместо ": table" в инструкции prepare, но привязка к нему работает, и я уверен, что он пытается связать имя таблицы. Кроме того, это необходимо привязать, потому что я хотел бы иметь возможность передавать имена моих таблиц через $_GET и такие.

Ответ 1

Можно ли связать имя таблицы?

Нет.

Вам нужно присваивать имена таблиц белого списка. Я сомневаюсь, что вы хотите, чтобы пользователь мог просматривать любую таблицу из вашей базы данных.

И вам также нужно отформатировать идентификаторы вручную. Существует пример тега wiki. Почему бы не прочитать его первым?

Update: Как вы можете видеть, PDO оказывается неудобным для реальных задач. Итак, для обработки запросов MySQL вы должны иметь более интеллектуальную библиотеку абстракции. Вот пример, используя класс safeMysql, который сделает ваш код значительно короче:

class form{
    public function __construct($table){
        global $db;
        return $db->getAll("DESCRIBE ?n", $table);
    }
}

2 примечания:

  • Я удалил второй параметр, поскольку в вашей функции нет кода.
  • НИКОГДА не подключайтесь к классу. Вместо этого используйте уже открытое соединение. Или вы убьете свой сервер MySQL с таким количеством подключений.

Исключить реализованную версию

class form {
    public function __construct($table,$skip = array("id")){
        global $db;
        $data = array();
        $res = $db->query("DESCRIBE ?n", $table);
        while($row = $db->fetch($res)) {
            if (!in_array($row['Field'],$skip)) {
                $data[] = $row;
            }
        }
        return $data;
    }
}

Однако такой класс редко может использоваться по назначению - всегда есть много исключений и ручного форматирования, чтобы сделать его пригодным для использования.

Ответ 2

Существует класс оболочки PDO при - http://www.phpclasses.org/package/5997-PHP-Database-access-abstraction-layer.html, который позволяет вам это сделать (хотя я новичок в PDO, поэтому, возможно, он не использует подготовленные заявления)

Его предлагаемое использование:

 $db = new DatabaseConnection('someMysqlServer', 'user', 'pass', 'database');

 $result = $db->exec($db->filterForSql('SELECT * FROM '.$tableName.';'));

Мне было бы интересно, если другие подумают, что это "безопасный" способ использования PDO или нет.