Я хочу создать главную страницу для своего учебного сайта (пытаюсь чему-то научиться), но у меня проблема (я думаю) с получением ответа на запрос.
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
}
Предупреждение. Ваш код уязвим для атак с использованием SQL-инъекций. Вам следует использовать параметризованные запросы и подготовленные операторы, чтобы предотвратить компрометацию вашей базы данных злоумышленниками с использованием вредоносных входных значений. bobby-tables.com дает объяснение рисков, а также несколько примеров того, как безопасно писать запросы с использованием PHP/mysqli. Никогда не вставляйте непараметризованные данные непосредственно в ваш SQL. Если ваш код написан сейчас, кто-то может легко украсть, неправильно изменить или даже удалить ваши данные.






Что ж, решение. Это не лучшее, что вы можете сделать, но оно работает.
<?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"] по массиву, содержащему белый список имен таблиц.
Да, вероятно, мне следует, но в моей базе данных нет реальных данных, и цель этого — просто научиться записывать данные из таблиц.
Чтобы делать все правильно, не требуется никаких дополнительных усилий, и это заложит у вас хорошие привычки, которые можно будет развивать. Вредные привычки имеют свойство закрепляться, поэтому лучше избегать их с самого начала.
Верный аргумент и хорошая идея для следующих «проектов» (я иду шаг за шагом)
Это ответ на ваш ответ, а не на ваш первоначальный вопрос.
Ваши текущие инструкции 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'];
}
(1) У вас есть две кнопки отправки, но обе имеют имя «ОК»?? (2)
$column = $conn->query($sqlcol)не будет помещать данные непосредственно в$column, если вы хотите получить данные, вам нужно использовать FETCH