本文提供一個基於Web的MySQL通用查詢工具:支持任意SQL語句輸入、區分「查詢」(SELECT)與「執行」(INSERT/UPDATE/DDL)、結果集表格化顯示、受影響行數統計,並處理magic_quotes_gpc兼容性問題。
<?php
// 1. 檢查並強制要求 magic_quotes_gpc = Off
if (get_magic_quotes_gpc() == 1) {
?>
<html><head><title>MySQL通用查詢程序</title></head>
<body>
注意:本程序要求 php.ini 中 magic_quotes_gpc = Off,修改後請重啟 Apache。
</body></html>
<?php exit(); ?>
<?php } ?>
set_magic_quotes_runtime(0); // 運行時關閉
// 2. 數據庫配置
$host = "localhost";
$db = "test";
$user = "test";
$pass = "";
// 3. URL編碼工具函數
function str2url($path) {
return eregi_replace("%2F", "/", urlencode($path));
}
?>
<html>
<head><title>MySQL通用查詢程序</title></head>
<body>
<form action="<?php echo str2url($PHP_SELF); ?>" method="post">
請輸入SQL語句:<br>
<textarea name="sql" cols="100" rows="5"><?php echo htmlspecialchars($sql ?? ''); ?></textarea><br>
<input type="submit" name="cmd" value="查詢">
<input type="submit" name="cmd" value="執行">
</form>
<?php
if ($cmd) {
// 4. 連接數據庫
$con = mysql_pconnect($host, $user, $pass) or die("無法連接 $host 服務器");
mysql_select_db($db, $con) or die("無法連接 $db 數據庫");
// 5. 執行SQL
$rst = mysql_query($sql, $con) or die("$sql 執行出錯: " . mysql_error());
if ($cmd == "查詢") {
// 6a. 查詢模式:表格化顯示結果集
$num_fields = mysql_num_fields($rst);
echo "<hr><table border='1' cellpadding='0' cellspacing='0'>";
echo "<caption align='center'>" . htmlspecialchars($sql) . "</caption>";
echo "<tr>";
for ($i = 0; $i < $num_fields; $i++) {
echo "<th> " . mysql_field_name($rst, $i) . "</th>";
}
echo "</tr>";
while ($row = mysql_fetch_row($rst)) {
echo "<tr>";
for ($i = 0; $i < $num_fields; $i++) {
echo "<td> " . htmlspecialchars($row[$i] ?? 'NULL') . "</td>";
}
echo "</tr>";
}
echo "</table>";
mysql_free_result($rst);
} else {
// 6b. 執行模式:顯示受影響行數
echo "有 " . mysql_affected_rows($con) . " 行受影響";
}
}
?>
</body></html>
| 特性 | 實現 | 安全/維護風險 |
|---|---|---|
| 任意SQL執行 | 直接mysql_query($sql) | 🔴 極高:無權限控制、無審計、可執行DROP DATABASE |
| magic_quotes處理 | 檢查GPC並拒絕運行 | 🟡 舊版PHP遺留問題,現代PHP已移除此特性 |
| 持久連接 | mysql_pconnect | 🟢 連接復用,但需注意連接數限制 |
| 結果集表格化 | 動態獲取字段名、逐行輸出 | 🟢 通用性好,大結果集內存壓力大 |
| 錯誤顯示 | die(mysql_error()) | 🟠 生產環境洩露敏感信息 |
<?php
// 僅允許特定IP/管理員訪問
if (!in_array($_SERVER['REMOTE_ADDR'], ['10.0.0.1', '192.168.1.100'])) {
http_response_code(403);
exit("Forbidden");
}
// 只讀模式:解析SQL,僅允許 SELECT/SHOW/EXPLAIN/DESC
$readonly = true;
$stmt = $pdo->prepare($sql);
$stmt->execute();
// 結果集分頁顯示
$page = max(1, (int)($_GET['page'] ?? 1));
$perPage = 50;
$offset = ($page - 1) * $perPage;
$stmt->execute(); // 重新執行獲取總數或使用 COUNT(*) 包裝查詢
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 表格渲染 (使用模板引擎)
echo $twig->render('sql_console.html.twig', [
'sql' => $sql,
'columns' => array_keys($rows[0] ?? []),
'rows' => $rows,
'page' => $page,
'total' => $total,
]);
// 審計日誌
AuditLog::create([
'user_id' => auth()->id(),
'sql' => $sql,
'type' => $readonly ? 'query' : 'execute',
'ip' => request()->ip(),
]);
此工具雖實現了「Web執行SQL」核心需求,但安全架構缺失嚴重。現代運維嚴禁在生產環境部署此類無權限控制的通用查詢界面,應採用審計、權限分級、只讀預設的專業工具。