Динамические имена таблиц и подготовленные операторы с использованием MySQLi - PullRequest
0 голосов
/ 08 октября 2019

Мне нужно сделать имена таблиц динамическими в моих запросах. Я читал, что вы не можете связать их, как с параметрами, поэтому я решил сделать что-то вроде этого:

$table_unsafe = $_GET['table'];
$table_safe = get_safe_table($mysqli, $table_unsafe);
$query = "SELECT * FROM " . $table_safe . " WHERE user=?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param('i', $user_id);

function get_safe_table($mysqli, $table)
{
    $query = "SELECT table_name FROM tables WHERE table_name=?";
    $stmt = $mysqli->prepare($query);
    $stmt->bind_param('s', $table);
    $stmt->execute();
    $result = $stmt->get_result();
    $result = $result->fetch_row();
    if ($result) {
        return $result[0];
    } else {
        exit;
    }
}

Таблица tables - это просто таблица, которая содержит вседоступные имена таблиц:

+-----+------------------+
| id  |    table_name    |
+-----+------------------+
|   1 | user_statistics  |
|   2 | user_information |
| ... | ...              |
+-----+------------------+

Безопасна ли эта практика? Если нет, что я могу сделать, чтобы сделать его более безопасным? Причина, по которой я помещаю доступные таблицы в таблицу, заключается в количестве таблиц, которые у меня есть (+300). Каждый раз, когда создается новая таблица, я просто добавляю строку в tables вместо того, чтобы постоянно обновлять мой код. Не существует общедоступного кода, который можно вставить или обновить tables.

1 Ответ

2 голосов
/ 08 октября 2019

Да, это возможно, но вам не нужно создавать таблицу для хранения имен таблиц и вести ее вручную - конечно, в mysql уже есть такая таблица. Так что это может быть просто

$sql = "SELECT 1 FROM information_schema.TABLES 
        WHERE TABLE_NAME = ? AND TABLE_SCHEMA IN (SELECT DATABASE())";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("s", $table);
$stmt->execute();
return (bool)$stmt->get_result()->fetch_row();

Однако использование должно быть немного другим. Нет смысла запускать запрос типа SELECT * FROM WHERE только с пустым именем таблицы. Вам следует только проверить результат функции и выдать ошибку, если она пуста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...