Как записать данные из таблицы SQL с помощью PhP (8.2)

Я хочу создать главную страницу для своего учебного сайта (пытаюсь чему-то научиться), но у меня проблема (я думаю) с получением ответа на запрос.

HTML для получения таблицы того, что я хочу. Значение в кнопке — это имя таблицы из базы данных.

<body>
  <div class = "s">
        <form  action = "table.php" method = "POST">
          <ul>
           <!-- <li><input class = "button" type = "submit" name = "ok" value = "**table name**"></li> -->
                <li><input class = "button" type = "submit" name = "ok" value = "name"></li>
                <li><input class = "button" type = "submit" name = "ok" value = "exam"></li>
           </ul>
        </form>
  </div>
</body>

Доктор философии

 if (isset($_POST["ok"])) 
    {
        $TableIWant = $_POST["ok"]; //Stores the name of the table
        $servername = "X";
        $username = "X";
        $password = "X";
        $dbname = "X";
        
        //Sql - gets column names?
        $sqlcol = "SELECT CONCAT('',GROUP_CONCAT(`COLUMN_NAME`),'') FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA`='$dbname' AND `TABLE_NAME`= '$TableIWant'";
        //create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        
        echo "$sqlcol <br>"; // writes out (just for chechk)
        $column = $conn->query($sqlcol);  
        echo "$column <br>";

// after I get column names I go and get the data from database and make table, but I am stuck on getting the column names
    }

(1) У вас есть две кнопки отправки, но обе имеют имя «ОК»?? (2) $column = $conn->query($sqlcol) не будет помещать данные непосредственно в $column, если вы хотите получить данные, вам нужно использовать FETCH

Ken Lee 24.04.2024 18:17

Предупреждение. Ваш код уязвим для атак с использованием SQL-инъекций. Вам следует использовать параметризованные запросы и подготовленные операторы, чтобы предотвратить компрометацию вашей базы данных злоумышленниками с использованием вредоносных входных значений. bobby-tables.com дает объяснение рисков, а также несколько примеров того, как безопасно писать запросы с использованием PHP/mysqli. Никогда не вставляйте непараметризованные данные непосредственно в ваш SQL. Если ваш код написан сейчас, кто-то может легко украсть, неправильно изменить или даже удалить ваши данные.

ADyson 24.04.2024 18:31
phpdelusions.net/mysqli также содержит хорошие примеры написания безопасного SQL с использованием mysqli. См. также документацию mysqli и это: Как я могу предотвратить SQL-инъекцию в PHP? . Параметризация запросов также значительно снизит риск случайных синтаксических ошибок в результате неэкранированных или неправильно заключенных в кавычки входных значений. Если вы изучили свою текущую технику из учебника или книги, пожалуйста, не используйте этот ресурс снова.
ADyson 24.04.2024 18:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
3
138
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Что ж, решение. Это не лучшее, что вы можете сделать, но оно работает.

<?php
if (isset($_POST["ok"])) {
// Get the table name from POST data
$TableIWant = $_POST["ok"];

// Database connection details
$servername = "servername";
$username = "username";
$password = "password";
$dbname = "dbname";

// Create a new connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check for connection errors
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// SQL query to get concatenated column names
$sqlcol = "SELECT GROUP_CONCAT(`COLUMN_NAME` SEPARATOR ', ') AS `columns`
           FROM `INFORMATION_SCHEMA`.`COLUMNS`
           WHERE `TABLE_SCHEMA` = '$dbname' AND `TABLE_NAME` = '$TableIWant'";

// Execute the query to get column names
$result = $conn->query($sqlcol);

if (!$result) {
    die("Query failed: " . $conn->error);
}

$row = $result->fetch_assoc();

if ($row) {
    // Split the concatenated column names into an array
    $columns = explode(", ", $row['columns']);

    // SQL query to fetch data from the specified table
    $sqlData = "SELECT * FROM `$TableIWant`"; // Query to fetch all data from the specified table

    $dataResult = $conn->query($sqlData); // Execute the query to get data

    if ($dataResult && $dataResult->num_rows > 0) {
        // Start the HTML table with centered alignment
        echo "<table border='1' style='margin: 0 auto; border: 1px solid black;'>";

        // Display the table header with column names
        echo "<tr>"; 
        foreach ($columns as $column) {
            echo "<th>$column</th>"; // Table headers for each column
        }
        echo "</tr>";

        // Display each row of data in the table
        while ($dataRow = $dataResult->fetch_assoc()) {
            echo "<tr>"; 
            foreach ($columns as $column) {
                echo "<td>" . $dataRow[$column] . "</td>"; // Output each data cell
            }
            echo "</tr>"; 
        }

        echo "</table>"; // End the table
    } else {
        echo "No data found in table '$TableIWant'.";
    }
} else {
    echo "No columns found for table '$TableIWant'.";
}

// Close the connection
$conn->close();
} 
?>

Как уже указывалось в комментариях к вашему вопросу, вы должны использовать параметризованные запросы и подготовленные операторы. Нет необходимости запускать отдельный запрос информационной схемы, чтобы получить имена столбцов, поскольку их можно получить с помощью $dataResult->fetch_fields(); или из строк в наборе результатов. Поскольку имена таблиц не могут быть параметризованы для вашего основного запроса выбора, вам следует проверить значение $_POST["ok"] по массиву, содержащему белый список имен таблиц.

user1191247 24.04.2024 20:59

Да, вероятно, мне следует, но в моей базе данных нет реальных данных, и цель этого — просто научиться записывать данные из таблиц.

jik 24.04.2024 22:20

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

user1191247 24.04.2024 22:29

Верный аргумент и хорошая идея для следующих «проектов» (я иду шаг за шагом)

jik 24.04.2024 22:36
Ответ принят как подходящий

Это ответ на ваш ответ, а не на ваш первоначальный вопрос.

Ваши текущие инструкции die по обработке ошибок ничего не сделают. Начиная с PHP 8.1.0, значением по умолчанию mysqli_driver::$report_mode является MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT, что означает, что при возникновении ошибки соединения или запроса будет выброшено исключение. Для получения более подробной информации об обработке ошибок вы можете прочитать эту статью об обработке ошибок.

Ваше «решение» использует ненужный отдельный запрос информационной схемы для получения имен столбцов и интерполирует переменные непосредственно в SQL. Параметризировать это тривиально, и я бы предположил, что еще важнее делать что-то «правильно» во время обучения, поскольку это помогает вам избежать формирования вредных привычек.

$sqlcol = "SELECT GROUP_CONCAT(`COLUMN_NAME` SEPARATOR ', ') AS `columns`
           FROM `INFORMATION_SCHEMA`.`COLUMNS`
           WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?";
$columns = $conn->execute_query($sqlcol, [$dbname, $TableIWant])->fetch_column();

Вместо запроса информационной схемы вы можете получить список столбцов с помощью mysqli_result::fetch_fields.

// SQL query to fetch data from the specified table
$dataResult = $conn->query("SELECT * FROM `$TableIWant`");

// Get columns list from result set
$columns = $dataResult->fetch_fields();

Теперь, когда $columns является массивом объектов, вы должны изменить итерацию заголовка столбца на:

foreach ($columns as $column) {
    echo "<th>$column->name</th>";
}

Приведенный выше запрос интерполируется $TableIWant непосредственно в SQL, поскольку имя таблицы не может быть параметризовано. Несмотря на то, что это только для вашего «обучающего сайта», это еще один хороший пример того, где вам следует реализовать некоторые разумные проверки. Если бы это было общедоступно, вы бы определенно не хотели, чтобы конечный пользователь получил все данные из любой таблицы, которую он хочет, или воспользовался уязвимостью, попытавшись атаковать SQL-инъекцию. Итак, чтобы гарантировать, что пользователь может получить доступ только к разрешенным таблицам, у вас должен быть белый список, что-то вроде:

$tableWhitelist = ['name', 'exam'];

if (isset($_POST['ok']) && in_array($_POST['ok'], $tableWhitelist)) {
    // do stuff
    $TableIWant = $_POST['ok'];
}

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