首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 導出 MySQL 完整 .sql 備份文件:結構與數據雙重導出實現

     編輯:PHP 相關知識

核心需求

  • 導出指定數據庫所有表結構(CREATE TABLE)
  • 導出所有表數據(INSERT 语句)
  • 生成單一 .sql 文件供下載
  • 執行完清理臨時文件

完整實現代碼

<?php
// 配置
$database = 'mydb';
$config = [
    'host' => 'localhost',
    'user' => 'backup_user',
    'pass' => 'backup_pass',
    'charset' => 'utf8mb4',
    'filename' => $database . '_' . date('Ymd_His') . '.sql'
];

// 連接
$mysqli = new mysqli($config['host'], $config['user'], $config['pass'], $database);
if ($mysqli->connect_errno) {
    die("連接失敗: {$mysqli->connect_error}");
}
$mysqli->set_charset($config['charset']);

// 獲取所有表
$tables = [];
$res = $mysqli->query("SHOW TABLES");
while ($row = $res->fetch_row()) $tables[] = $row[0];
$res->free();

// 打開輸出文件
$fp = fopen($config['filename'], 'w');
if (!$fp) die('無法創建輸出文件');

// 寫入文件頭
fwrite($fp, "-- MySQL 備份文件\n");
fwrite($fp, "-- 數據庫: {$database}\n");
fwrite($fp, "-- 生成時間: " . date('Y-m-d H:i:s') . "\n\n");
fwrite($fp, "SET FOREIGN_KEY_CHECKS=0;\n\n");

foreach ($tables as $table) {
    // 1. 導出表結構
    $createRes = $mysqli->query("SHOW CREATE TABLE `{$table}`");
    $createRow = $createRes->fetch_assoc();
    fwrite($fp, "-- 表結構: {$table}\n");
    fwrite($fp, "DROP TABLE IF EXISTS `{$table}`;\n");
    fwrite($fp, $createRow['Create Table'] . ";\n\n");
    $createRes->free();

    // 2. 導出數據
    $dataRes = $mysqli->query("SELECT * FROM `{$table}`");
    if ($dataRes->num_rows > 0) {
        fwrite($fp, "-- 數據: {$table}\n");
        while ($row = $dataRes->fetch_assoc()) {
            $cols = array_keys($row);
            $vals = array_map(function($v) use ($mysqli) {
                return $v === null ? 'NULL' : "'" . $mysqli->real_escape_string($v) . "'";
            }, $row);
            fwrite($fp, "INSERT INTO `{$table}` (`" . implode('`, `', $cols) . "`) VALUES (" . implode(', ', $vals) . ");\n");
        }
        fwrite($fp, "\n");
    }
    $dataRes->free();
}

fwrite($fp, "SET FOREIGN_KEY_CHECKS=1;\n");
fclose($fp);

// 下載輸出
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($config['filename']) . '"');
header('Content-Length: ' . filesize($config['filename']));
readfile($config['filename']);

// 清理
unlink($config['filename']);
$mysqli->close();
exit;

關鍵點解析

環節處理方式原因
表結構SHOW CREATE TABLE獲取完整建表語句含索引、引擎、字符集
數據轉義mysqli_real_escape_string防止特殊字符破壞 SQL 語法
NULL 處理顯式輸出 NULL 而非空字符串保持數據語義準確
外鍵約束SET FOREIGN_KEY_CHECKS=0/1導入時避免順序依賴報錯
內存控制逐行寫入文件,不載入全量數據支援大數據庫不 OOM

增強版功能建議

  • 支援壓縮輸出:gzopen 寫入 .sql.gz
  • 支援單表/多庫導出參數化
  • 添加 --single-transaction 邏輯(需 SELECT 權限)
  • 集成到控制台命令(Symfony Console / Laravel Artisan)
  • 上傳至雲存儲(S3/OSS)而非本地下載

對比 mysqldump

維度PHP 實現mysqldump
性能較慢(PHP 解析開銷)極快(C 級別、流式)
可定制極高(業務邏輯可介入)參數固定
部署依賴僅需 PHP mysqli需 mysqldump 二進制、權限
適用場景Web 界面手動導出、特殊過濾定時自動備份、大數據庫

總結

PHP 導出 .sql 適用於「Web 界面按需導出、需業務過濾、無服務器 Shell 權限」場景。生產級定時備份仍首選 mysqldump --single-transaction --routines --triggers --events 配合壓縮上傳。代碼核心在於:逐表結構+數據流式寫入、完整轉義、外鍵暫用、內存可控。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved