早期範例使用已移除的 mysql_list_dbs()。現代 PHP 使用 mysqli 或 PDO 執行 SHOW DATABASES,並妥善處理權限、字元集、錯誤。本文提供完整實作,包含過濾系統資料庫、取得資料庫大小、建立選單/下拉選單。
<?php
$mysqli = new mysqli('localhost', 'user', 'password');
if ($mysqli->connect_errno) {
die("連線失敗 ({$mysqli->connect_errno}): {$mysqli->connect_error}");
}
$mysqli->set_charset('utf8mb4');
$result = $mysqli->query('SHOW DATABASES');
if (!$result) {
die("查詢失敗: {$mysqli->error}");
}
$databases = [];
while ($row = $result->fetch_row()) {
$db = $row[0];
// 過濾系統資料庫
if (!in_array($db, ['information_schema', 'performance_schema', 'mysql', 'sys'])) {
$databases[] = $db;
}
}
$result->free();
$mysqli->close();
// 輸出 HTML 選單
echo '<select name="database">';
echo '<option value="">-- 請選擇資料庫 --</option>';
foreach ($databases as $db) {
echo '<option value="' . htmlentities($db) . '">' . htmlentities($db) . '</option>';
}
echo '</select>';
?>
<?php
$dsn = 'mysql:host=localhost;charset=utf8mb4';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_COLUMN, // 直接取得第一欄
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, 'user', 'password', $options);
$databases = $pdo->query('SHOW DATABASES')->fetchAll();
// 過濾系統庫
$systemDbs = ['information_schema', 'performance_schema', 'mysql', 'sys'];
$databases = array_filter($databases, fn($db) => !in_array($db, $systemDbs));
// 取得每個資料庫大小(選用)
$sizes = [];
if ($databases) {
$placeholders = implode(',', array_fill(0, count($databases), '?'));
$stmt = $pdo->prepare("
SELECT table_schema, SUM(data_length + index_length) AS total_size
FROM information_schema.tables
WHERE table_schema IN ($placeholders)
GROUP BY table_schema
");
$stmt->execute($databases);
foreach ($stmt->fetchAll(PDO::FETCH_KEY_PAIR) as $db => $size) {
$sizes[$db] = $size;
}
}
// 輸出
echo '<ul>';
foreach ($databases as $db) {
$size = isset($sizes[$db]) ? formatBytes($sizes[$db]) : '未知';
echo "<li>" . htmlentities($db) . " <small>($size)</small></li>";
}
echo '</ul>';
} catch (PDOException $e) {
die("資料庫錯誤: {$e->getMessage()}");
}
function formatBytes(int $bytes): string
{
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$i = 0;
while ($bytes >= 1024 && $i < count($units) - 1) {
$bytes /= 1024;
$i++;
}
return round($bytes, 2) . ' ' . $units[$i];
}
?>
<?php
$mysqli = new mysqli('localhost', 'user', 'password');
$mysqli->set_charset('utf8mb4');
$sql = "
SELECT
SCHEMA_NAME AS `database`,
DEFAULT_CHARACTER_SET_NAME AS `charset`,
DEFAULT_COLLATION_NAME AS `collation`,
(SELECT SUM(data_length + index_length) FROM information_schema.tables WHERE table_schema = SCHEMA_NAME) AS `size_bytes`,
CREATE_TIME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME NOT IN ('information_schema','performance_schema','mysql','sys')
ORDER BY SCHEMA_NAME
";
$result = $mysqli->query($sql);
$databases = $result->fetch_all(MYSQLI_ASSOC);
$result->free();
echo '<table border="1" cellpadding="6">';
echo '<tr><th>資料庫</th><th>編碼</th><th>排序規則</th><th>大小</th><th>建立時間</th></tr>';
foreach ($databases as $db) {
echo '<tr>';
echo '<td>' . htmlentities($db['database']) . '</td>';
echo '<td>' . htmlentities($db['charset']) . '</td>';
echo '<td>' . htmlentities($db['collation']) . '</td>';
echo '<td>' . ($db['size_bytes'] ? formatBytes($db['size_bytes']) : '-') . '</td>';
echo '<td>' . ($db['CREATE_TIME'] ? date('Y-m-d H:i:s', strtotime($db['CREATE_TIME'])) : '-') . '</td>';
echo '</tr>';
}
echo '</table>';
?>
列出資料庫只需 SHOW DATABASES 權限。建立專用帳號:
CREATE USER 'db_lister'@'%' IDENTIFIED BY 'strong_password';
GRANT SHOW DATABASES ON *.* TO 'db_lister'@'%';
FLUSH PRIVILEGES;
若需查詢大小,額外授權:
GRANT SELECT ON information_schema.tables TO 'db_lister'@'%';
| 問題 | 解決 |
|---|---|
| 看不到剛建立的資料庫 | 檢查使用者是否有該資料庫的任意權限(GRANT SELECT ON db.* TO user),MySQL 預設只顯示有權限的資料庫。 |
| 大小顯示 NULL | information_schema.tables 統計僅含有表的資料庫,空資料庫大小為 NULL。 |
| 編碼顯示 latin1 | 資料庫建立時未指定 CHARSET,預設 latin1。建議建立時指定 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci。 |
| 效能慢 | information_schema 查詢在資料庫極多(千個以上)時較慢。可快取結果、或只查 SHOW DATABASES 不 join 大小。 |
set_charset('utf8mb4') / DSN 加 charset=utf8mb4。information_schema、performance_schema、mysql、sys)。SHOW DATABASES、SELECT ON information_schema.tables。掌握現代列表資料庫寫法,不僅相容 PHP 8+,更能建構安全、可維護的資料庫管理介面。