在自動化部署、安裝向導、數據遷移等場景中,常需通過 PHP 讀取 .sql 文件並批量執行導入 MySQL。本文提供一個健壯、支援自定義資料庫名稱的完整方案。
// 讀取 SQL 文件內容
$sqlContent = file_get_contents('test.sql');
// 按分號分割語句(簡易分割,注意存儲過程、觸發器內可能含分號)
$statements = explode(';', $sqlContent);
// 連接資料庫
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS);
if ($mysqli->connect_errno) {
exit('資料庫連接失敗: ' . $mysqli->connect_error);
}
// 逐條執行
foreach ($statements as $stmt) {
$stmt = trim($stmt);
if ($stmt === '') continue; // 跳過空語句
if (!$mysqli->query($stmt)) {
error_log("SQL 執行失敗: {$mysqli->error}\nSQL: $stmt");
}
}
$mysqli->close();
若 SQL 文件包含 CREATE DATABASE 與 USE,需動態替換:
$dbName = 'my_project_db'; // 可從配置或用戶輸入獲取
$sqlContent = file_get_contents('test.sql');
// 移除文件中的 CREATE DATABASE 和 USE 語句(簡單正則,視具體 SQL 結構調整)
$sqlContent = preg_replace('/CREATE\s+DATABASE\s+IF\s+NOT\s+EXISTS\s+\w+\s*;/i', '', $sqlContent);
$sqlContent = preg_replace('/USE\s+\w+\s*;/i', '', $sqlContent);
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS);
if ($mysqli->connect_errno) exit('連接失敗');
// 先創建資料庫並選擇
$mysqli->query("CREATE DATABASE IF NOT EXISTS `$dbName` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;");
$mysqli->query("USE `$dbName`;");
// 再執行剩餘語句
$statements = explode(';', $sqlContent);
foreach ($statements as $stmt) {
$stmt = trim($stmt);
if ($stmt) $mysqli->query($stmt);
}
$mysqli->close();
$mysqli->begin_transaction()、commit()/rollback() 保證原子性。explode(';') 會誤切存儲過程、觸發器、多行字符串內的分號。生產環境建議使用 mysqldump-php 或 php-sql-parser 庫。fgets() 逐行讀取緩衝執行,避免記憶體溢出。utf8mb4,防止亂碼。connect_errno) die("連接失敗\n");
$mysqli->query("CREATE DATABASE IF NOT EXISTS `$db` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;");
$mysqli->query("USE `$db`;");
$stmts = explode(';', $sql);
$success = $fail = 0;
foreach ($stmts as $i => $stmt) {
$stmt = trim($stmt);
if (!$stmt) continue;
if ($mysqli->query($stmt)) {
$success++;
} else {
$fail++;
echo "第 $i 條失敗: {$mysqli->error}\n";
}
}
echo "完成: 成功 $success, 失敗 $fail\n";
$mysqli->close();
將上述代碼保存為 import_sql.php,即可通過命令行一鍵導入:php import_sql.php backup.sql my_database。