phpMyAdmin 雖然方便,但在處理超大數據集(如 10MB+)時,常因 PHP 上傳限制(預設 2MB)、單引號轉義錯誤等問題導致導入失敗。本文分享一套基於 PHP + 文本文件的「導出結構用 phpMyAdmin,導數據用腳本」的實戰方案,親測可穩定處理千萬級數據。
<?php
// 參數檢查
if (empty($_GET['table'])) exit();
$table = $_GET['table'];
// 連接資料庫(建議改用 mysqli/PDO)
mysql_connect("localhost", "user", "pass");
mysql_select_db("dbname");
$result = mysql_query("SELECT * FROM `$table`");
if (mysql_num_rows($result) == 0) exit();
$handle = fopen("$table.txt", "w");
$num_fields = mysql_num_fields($result);
// 首行寫入欄位數,便於導入時解析
fwrite($handle, $num_fields . "\r\n");
while ($row = mysql_fetch_row($result)) {
for ($i = 0; $i < $num_fields; $i++) {
// 將換行符統一替換為特殊標記,避免文本行混亂
$val = str_replace(["\r\n", "\n"], "&&php2000mysqlreturn&&", $row[$i]);
fwrite($handle, $val . "\r\n");
}
// 每行結束標記(可選,便於校驗)
fwrite($handle, "------- php2000 dump data program V1.0 for MySQL --------\r\n");
}
fclose($handle);
echo "ok";
?>
<?php
if (empty($_GET['table'])) exit();
$table = $_GET['table'];
mysql_connect("localhost", "user", "pass");
mysql_select_db("dbname");
$lines = file("$table.txt"); // 10MB 內可用;超大文件建議改用 fopen/fgets 逐行讀取
$num_fields = (int)trim($lines[0]);
$total_lines = count($lines);
for ($k = 1; $k < $total_lines; $k += $num_fields + 1) { // +1 跳過結束標記行
$values = [];
for ($i = 0; $i < $num_fields; $i++) {
$idx = $k + $i;
if ($idx >= $total_lines) break;
// 還原換行符並轉義單引號
$val = str_replace("&&php2000mysqlreturn&&", "\r\n", trim($lines[$idx]));
$values[] = "'" . addslashes($val) . "'";
}
if (count($values) === $num_fields) {
$sql = "INSERT INTO `$table` VALUES (" . implode(',', $values) . ")";
mysql_query($sql);
echo mysql_error() . " $k ";
}
}
echo "ok";
?>
\r\n/\n 替換為唯一標記(如 &&php2000mysqlreturn&&),導入時還原,完美保留文本格式。file() 會一次性載入記憶體,超過 50MB 建議改用 fopen() + fgets() 逐行處理。LOAD DATA INFILE 替代 INSERT 大幅提速。若頻繁處理大數據遷移,建議直接使用 MySQL 原生工具:
mysqldump --tab=/path --fields-terminated-by=',' --lines-terminated-by='\n' 導出文本mysqlimport 或 LOAD DATA INFILE 高速導入Percona XtraBackup 進行物理熱備份與還原這套腳本方案無需修改 php.ini、無依賴第三方庫,適合虛擬主機、無權限修改服務器配置的場景,是中小型專案遷移大數據的實用利器。