資料庫備份是系統維護的核心環節。本文提供一個基於 PHP 的 MySQL 整庫備份腳本,支援結構與資料完整導出,生成標準 SQL 檔案,可直接用於還原或遷移。
<?php
ini_set("max_execution_time", "180"); // 防止大資料庫導出超時
$host = ""; // 資料庫主機
$dbname = ""; // 資料庫名稱
$username = ""; // 使用者名稱
$passw = ""; // 密碼
$filename = date("Y-m-d_H-i-s") . "-" . $dbname . ".sql";
// 設定下載 Header
header("Content-disposition: filename=" . $filename);
header("Content-type: application/octet-stream");
header("Pragma: no-cache");
header("Expires: 0");
$crlf = "\r\n";
$dbconn = mysql_connect($host, $username, $passw);
mysql_select_db($dbname, $dbconn);
mysql_query("SET NAMES 'utf8'");
$tables = mysql_list_tables($dbname, $dbconn);
$num_tables = @mysql_num_rows($tables);
echo "-- filename=" . $filename;
for ($i = 0; $i < $num_tables; $i++) {
$table = mysql_tablename($tables, $i);
echo $crlf;
// 輸出資料表結構
echo get_table_structure($dbname, $table, $crlf) . ";{$crlf}{$crlf}";
// 輸出資料表資料
echo get_table_content($dbname, $table, $crlf);
}
使用 SHOW CREATE TABLE 直接獲取完整建表語句,保留引擎、字符集、自增值、註釋等完整資訊:
function get_table_structure($db, $table, $crlf) {
global $drop;
$schema_create = "";
if (!empty($drop)) {
$schema_create .= "DROP TABLE IF EXISTS `$table`;$crlf";
}
$result = mysql_db_query($db, "SHOW CREATE TABLE $table");
$row = mysql_fetch_array($result);
$schema_create .= $crlf . "-- " . $row[0] . $crlf;
$schema_create .= $row[1] . $crlf;
return $schema_create;
}
function get_table_content($db, $table, $crlf) {
$schema_create = "";
$temp = "";
$result = mysql_db_query($db, "SELECT * FROM $table");
$i = 0;
while ($row = mysql_fetch_row($result)) {
$schema_insert = "INSERT INTO `$table` VALUES (";
for ($j = 0; $j < mysql_num_fields($result); $j++) {
if (!isset($row[$j])) {
$schema_insert .= " NULL,";
} elseif ($row[$j] != "") {
$schema_insert .= " '" . addslashes($row[$j]) . "',";
} else {
$schema_insert .= " '',";
}
}
$schema_insert = preg_replace("/,$/", "", $schema_insert);
$schema_insert .= ");$crlf";
$temp .= $schema_insert;
$i++;
}
return $temp;
}
原代碼使用已棄用的 mysql_* 函數族群(PHP 5.5.0 棄用,PHP 7.0.0 移除)。生產環境必須遷移至 mysqli 或 PDO。
// 使用 PDO 版本片段
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $passw);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$tables = $pdo->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN);
foreach ($tables as $table) {
// 結構
$stmt = $pdo->query("SHOW CREATE TABLE `$table`");
$row = $stmt->fetch(PDO::FETCH_NUM);
echo $row[1] . ";\n\n";
// 資料
$stmt = $pdo->query("SELECT * FROM `$table`");
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$values = array_map(function($v) use ($pdo) {
return $v === null ? 'NULL' : $pdo->quote($v);
}, $row);
echo "INSERT INTO `$table` VALUES (" . implode(',', $values) . ");\n";
}
}
LIMIT offset, count 分頁查詢gzip 壓縮 SQL 檔案SELECT, LOCK TABLES, SHOW VIEW 權限| 工具 | 適用場景 | 優點 |
|---|---|---|
| mysqldump | 生產環境標準備份 | 官方工具、效能最佳、支援熱備份、壓縮、單一交易 |
| Percona XtraBackup | 大型線上資料庫 | 實體熱備份、不鎖表、增量備份、備份速度極快 |
| PHP 腳本 | 無 Shell 存取權限的虛擬主機 | 純 PHP 實作、透過 HTTP 下載、易於整合至後台管理 |
雖然 PHP 實現的備份腳本在虛擬主機環境下具備獨特優勢,但生產環境強烈建議使用 mysqldump 或專業備份工具。若必須使用 PHP 方案,請務必升級至 PDO/MySQLi、加入異步處理機制,並定期驗證備份檔案可還原性。