我想为我的学习网站创建一个主页(尝试学习东西),但我有一个问题(我认为)从查询中获取响应。
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>
PhP
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
}
您当前用于处理错误的
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'];
}
<?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();
}
?>