虛擬主機環境常限制 upload_max_filesize、post_max_size、max_execution_time,導致 phpMyAdmin 匯入大型 SQL 檔案失敗。自製 PHP 腳本可分批處理、繞過限制。
&&jimmy&&)區隔,避免資料本身含分隔符衝突<?php
// 設定
$host = 'localhost';
$user = 'root';
$pass = '';
$dbname = 'your_db';
$table = 'your_table';
$output = $table . '.txt';
$mysqli = new mysqli($host, $user, $pass, $dbname);
if ($mysqli->connect_errno) {
die('Connect failed: ' . $mysqli->connect_error);
}
$mysqli->set_charset('utf8mb4');
$result = $mysqli->query("SELECT * FROM `$table`");
if (!$result || $result->num_rows === 0) {
die('No data or error: ' . $mysqli->error);
}
$fp = fopen($output, 'w');
$fieldCount = $result->field_count;
fwrite($fp, $fieldCount . " "); // 寫入欄位數
$delimiter = '&&jimmy&&';
while ($row = $result->fetch_row()) {
foreach ($row as $i => $val) {
// 轉義分隔符與換行
$val = str_replace($delimiter, $delimiter . $delimiter, $val);
$val = str_replace("\n", '\n', $val);
$val = str_replace("\r", '\r', $val);
fwrite($fp, $val . " ");
}
fwrite($fp, "------- PHP MySQL Dump V1.0 -------- ");
}
fclose($fp);
$mysqli->close();
echo "Export done: $output";
?>
<?php
$host = 'localhost';
$user = 'root';
$pass = '';
$dbname = 'your_db';
$table = 'your_table';
$input = $table . '.txt';
$mysqli = new mysqli($host, $user, $pass, $dbname);
if ($mysqli->connect_errno) die('Connect failed: ' . $mysqli->connect_error);
$mysqli->set_charset('utf8mb4');
$lines = file($input, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if (!$lines) die('File empty');
$fieldCount = (int)trim(array_shift($lines));
$delimiter = '&&jimmy&&';
$batch = [];
$batchSize = 1000; // 批次提交
foreach ($lines as $line) {
if (strpos($line, '------- PHP MySQL Dump') !== false) continue; // 跳過分隔行
$parts = explode(' ', $line, $fieldCount);
if (count($parts) !== $fieldCount) continue; // 格式錯誤跳過
$values = [];
foreach ($parts as $val) {
$val = str_replace($delimiter . $delimiter, $delimiter, $val);
$val = str_replace('\n', "\n", $val);
$val = str_replace('\r', "\r", $val);
$values[] = "'" . $mysqli->real_escape_string($val) . "'";
}
$batch[] = '(' . implode(',', $values) . ')';
if (count($batch) >= $batchSize) {
$sql = "INSERT INTO `$table` VALUES " . implode(',', $batch);
if (!$mysqli->query($sql)) {
error_log("Import error: " . $mysqli->error . " SQL: $sql");
}
$batch = [];
}
}
// 餘數提交
if ($batch) {
$sql = "INSERT INTO `$table` VALUES " . implode(',', $batch);
$mysqli->query($sql);
}
$mysqli->close();
echo "Import completed.";
?>
mysqli 取代已棄用的 mysql 擴展real_escape_string 防止 SQL 注入batchSize)大幅提升匯入效能mysqldump --single-transaction --quick 熱備份LOAD DATA INFILE 替代 INSERT,速度快 10-20 倍