單一檔案透過 $cmd 參數控制三種檢視模式:
?cmd=db(預設) — 列出伺服器所有資料庫?cmd=table&db=資料庫名 — 列出該資料庫所有資料表?cmd=record&db=資料庫名&table=資料表名 — 以表格顯示該資料表所有記錄<?php
$host = 'localhost';
$user = 'test';
$password = '';
$cmd = $_GET['cmd'] ?? 'db';
$db = $_GET['db'] ?? '';
$table = $_GET['table'] ?? '';
// 合法 cmd 白名單
$allowedCmd = ['db', 'table', 'record'];
if (!in_array($cmd, $allowedCmd)) $cmd = 'db';
$con = @mysqli_connect($host, $user, $password);
if (!$con) die('無法連線 ' . $host . ': ' . mysqli_connect_error());
switch ($cmd) {
case 'db':
$res = mysqli_query($con, 'SHOW DATABASES');
echo 'Databases on ' . htmlspecialchars($host) . ':<br>';
while ($row = mysqli_fetch_row($res)) {
$dbName = urlencode($row[0]);
echo " <a href='?cmd=table&db=$dbName'>{$row[0]}</a><br>";
}
mysqli_free_result($res);
break;
case 'table':
if (!$db) { echo '缺少 db 參數'; break; }
mysqli_select_db($con, $db);
$res = mysqli_query($con, 'SHOW TABLES');
echo 'Tables in ' . htmlspecialchars($db) . ' on ' . htmlspecialchars($host) . ':<br>';
while ($row = mysqli_fetch_row($res)) {
$tbl = urlencode($row[0]);
echo " <a href='?cmd=record&db=" . urlencode($db) . "&table=$tbl'>{$row[0]}</a><br>";
}
mysqli_free_result($res);
echo '<hr><a href="?cmd=db">Show Databases</a>';
break;
case 'record':
if (!$db || !$table) { echo '缺少 db 或 table 參數'; break; }
mysqli_select_db($con, $db);
$safeTable = mysqli_real_escape_string($con, $table);
$res = mysqli_query($con, "SELECT * FROM `$safeTable`");
if (!$res) { die('查詢錯誤: ' . mysqli_error($con)); }
echo 'Records in ' . htmlspecialchars($table) . ':<br>';
echo '<table border="1" cellspacing="0" cellpadding="4"><tr>';
$fields = mysqli_num_fields($res);
for ($i = 0; $i < $fields; $i++) {
$finfo = mysqli_fetch_field_direct($res, $i);
echo '<th>' . htmlspecialchars($finfo->name) . '</th>';
}
echo '</tr>';
while ($row = mysqli_fetch_row($res)) {
echo '<tr>';
foreach ($row as $val) echo '<td>' . htmlspecialchars($val ?? 'NULL') . '</td>';
echo '</tr>';
}
echo '</table>';
mysqli_free_result($res);
echo '<hr>';
echo '<a href="?cmd=db">Show Databases</a> ';
echo '<a href="?cmd=table&db=' . urlencode($db) . '">Show Tables</a>';
break;
}
mysqli_close($con);
?>
| 原始寫法 | 問題 | 修正版 |
|---|---|---|
mysql_* 函數 | PHP 7.0 移除 | mysqli_* 物件導向/程序式均可 |
直接拼接 $table 進 SQL | SQL 注入風險(雖為識別碼,仍需跳脫) | mysqli_real_escape_string + 反引號包裹 |
$PHP_SELF 直接輸出 | XSS 風險 | 建議用 $_SERVER['PHP_SELF'] 經 htmlspecialchars |
| 無參數驗證 | 缺參數時產生 Notice/Warning | Null coalescing ?? 給預設值 |
| 硬編碼帳密 | 原始碼洩露風險 | 建議從 .env 或環境變數讀取 |
LIMIT $offset, $perPage + 總筆數 SELECT COUNT(*)WHERE `col` LIKE ? 參數化查詢fputcsv 或 json_encode 輸出db_browser.php,勿放於公開目錄下無保護存取