背景痛點
- phpMyAdmin 導入受限於
upload_max_filesize/post_max_size (預設 2M),大檔案失敗。
- .sql 匯入常因單引號、特殊字元導致語法錯誤。
- 需跨伺服器遷移,需 FTP 傳輸中轉。
核心設計:分表導出、純文字儲存、自定義轉義
導出腳本 (export.php?table=tablename)
<?php
if (empty($_GET['table'])) exit;
$table = $_GET['table'];
$conn = mysqli_connect('localhost', 'user', 'pass', 'db');
$res = mysqli_query($conn, "SELECT * FROM `$table`");
if (mysqli_num_rows($res) == 0) exit;
$fp = fopen("$table.txt", 'w');
$fields = mysqli_num_fields($res);
fwrite($fp, "$fields\r\n"); // 首行寫欄位數
while ($row = mysqli_fetch_row($res)) {
for ($i = 0; $i < $fields; $i++) {
// 統一轉義換行符,避免行數錯亂
$val = str_replace(["\r\n", "\n"], '&&PHP2000MYSQLRETURN&&', $row[$i]);
fwrite($fp, "$val\r\n");
}
// 每行結束標記,便於導入識別邊界
fwrite($fp, "------- PHP2000 DUMP DATA PROGRAM V1.0 FOR MYSQL -------\r\n");
}
fclose($fp);
echo "ok";
?>
導入腳本 (import.php?table=tablename)
<?php
if (empty($_GET['table'])) exit;
$table = $_GET['table'];
$conn = mysqli_connect('localhost', 'user', 'pass', 'db');
$lines = file("$table.txt"); // 注意:大檔案可能記憶體不足,建議改 fopen 逐行讀取
$fields = (int)trim($lines[0]);
for ($k = 1; $k < count($lines); $k += $fields + 1) {
$values = [];
for ($i = $k; $i < $k + $fields - 1; $i++) {
$val = str_replace('&&PHP2000MYSQLRETURN&&', "\r\n", trim($lines[$i]));
$values[] = "'" . mysqli_real_escape_string($conn, $val) . "'";
}
// 最後一欄
$val = str_replace('&&PHP2000MYSQLRETURN&&', "\r\n", trim($lines[$k + $fields - 1]));
$values[] = "'" . $val . "'";
$sql = "INSERT INTO `$table` VALUES (" . implode(',', $values) . ")";
mysqli_query($conn, $sql);
echo mysqli_error($conn) . " $k ";
}
echo "ok";
?>
關鍵技術細節
| 問題 | 解決方案 |
| 欄位內含換行符 | 統一替換為 &&PHP2000MYSQLRETURN&& 佔位符,導入時還原 |
| 單引號/特殊字元 | 導入時用 mysqli_real_escape_string() 轉義 |
| 大檔案 memory_limit | 導入改用 fopen() + fgets() 逐行處理,不一次性 file() |
| 跨伺服器傳輸 | 導出後 FTP 上傳本地;導入前 FTP 下載到目標伺服器 |
| 結構與資料分離 | phpMyAdmin 導出結構 (--no-data),腳本只處理資料 |
改進建議 (生產級)
- 改用
mysqli_multi_query 批次執行,減少往返延遲。
- 加入事務控制:每 1000 行
COMMIT,失敗可回滾。
- 導出端支援
WHERE 條件分片導出 (如按 ID 範圍),平行處理。
- 記錄導出/導入進度、檢查和 (CRC32)、行數,驗證完整性。
- 考慮直接用
mysqldump --tab + mysqlimport 替代自製腳本,效能更強、維護更低。