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

ThinkPHP 資料庫備份匯出功能實作:PDO 版完整原始碼支援結構與資料

     編輯:PHP 綜合知識

ThinkPHP 核心未內建資料庫備份功能,本文提供一個基於 PDO 的 SqlAction 控制器,支援完整匯出資料庫結構 (建庫、建表) 與資料 (INSERT 語句),並自動處理字元集、排序規則、特殊字元跳脫,生成可直接執行的 .sql 檔案供下載。

核心功能特色

  • 使用 PDO 連線,支援異常處理、預處理語句
  • 自動讀取 ThinkPHP 配置 C('DB_*'),無需重複設定
  • 匯出內容包含:DROP DATABASE、CREATE DATABASE (含字元集/排序)、USE、DROP TABLE、CREATE TABLE、INSERT INTO
  • 欄位名與值自動 addslashes 跳脫,防止 SQL 語法錯誤
  • 支援 $flag 參數控制是否匯出資料 (0=僅結構, 1=結構+資料)
  • 直接輸出 Content-Disposition: attachment 觸發瀏覽器下載

完整控制器程式碼 SqlAction.class.php

<?php
class SqlAction extends Action {
    public function outsql() {
        header("Content-Type: text/html; charset=utf-8");

        // 讀取 ThinkPHP 資料庫配置
        $host     = C('DB_HOST');
        $db_name  = C('DB_NAME');
        $user     = C('DB_USER');
        $password = C('DB_PWD');

        // 呼叫私有匯出方法
        $outstream = $this->outputSql($host, $db_name, $user, $password);

        // 觸發下載
        header("Content-Disposition: attachment; filename={$db_name}.sql");
        echo $outstream;
    }

    /**
     * 資料庫匯出核心方法
     * @param string $host     主機位址
     * @param string $dbname   資料庫名稱
     * @param string $user     使用者名稱
     * @param string $password 密碼
     * @param int    $flag     0=僅結構, 1=結構+資料 (預設)
     * @return string 完整 SQL 字串
     */
    private function outputSql($host, $dbname, $user, $password, $flag = 1) {
        try {
            $pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $password);
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            echo $e->getMessage();
            exit;
        }

        $mysql = "DROP DATABASE IF EXISTS `$dbname`;\n";

        // 取得建庫語句以擷取字元集
        $creat_db = $pdo->query("SHOW CREATE DATABASE `$dbname`")->fetch();
        preg_match('/DEFAULT CHARACTER SET (.*)\*/', $creat_db['Create Database'], $matches);
        $mysql .= "CREATE DATABASE `$dbname` DEFAULT CHARACTER SET {$matches[1]}";

        // 取得排序規則
        $db_collate = $pdo->query(
            "SELECT DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = '$dbname' LIMIT 1"
        )->fetch();
        $mysql .= " COLLATE {$db_collate['DEFAULT_COLLATION_NAME']};\nUSE `$dbname`;\n\n";

        // 遍歷所有資料表
        $statments = $pdo->query("SHOW TABLES");
        foreach ($statments as $value) {
            $table_name = $value[0];
            $mysql .= "DROP TABLE IF EXISTS `$table_name`;\n";

            // 取得建表語句
            $table_query = $pdo->query("SHOW CREATE TABLE `$table_name`");
            $create_sql = $table_query->fetch();
            $mysql .= $create_sql['Create Table'] . ";\r\n\r\n";

            // 匯出資料
            if ($flag != 0) {
                $iteams_query = $pdo->query("SELECT * FROM `$table_name`");
                $values = "";
                $items = "";

                while ($item_query = $iteams_query->fetch(PDO::FETCH_ASSOC)) {
                    $item_names = array_keys($item_query);
                    $item_names = array_map('addslashes', $item_names);
                    $items = join('`,`', $item_names);

                    $item_values = array_values($item_query);
                    $item_values = array_map('addslashes', $item_values);
                    $value_string = join("','", $item_values);
                    $value_string = "('" . $value_string . "'),";

                    $values .= "\n" . $value_string;
                }

                if ($values != "") {
                    $insert_sql = "INSERT INTO `$table_name` (`$items`) VALUES" . rtrim($values, ",") . ";\n\r";
                    $mysql .= $insert_sql;
                }
            }
        }

        return $mysql;
    }
}
?>

使用方式

  1. 將檔案放入 Lib/Action/SqlAction.class.php
  2. 瀏覽器存取 https://yourdomain.com/index.php/Sql/outsql
  3. 瀏覽器自動下載 資料庫名.sql
  4. 下載檔案可直接用 mysql -u root -p < backup.sql 還原

擴充建議

  • 支援 mysqli / mysqlnd: 依專案實際資料庫驅動調整連線方式
  • 分卷壓縮: 大型資料庫可配合 gzencode() 壓縮並分割下載
  • 定時備份: 結合 Linux crontab + CLI 模式 (php index.php Sql outsql) 實現自動化備份
  • 雲端同步: 備份完成後上傳至 S3/OSS/COS 等物件存儲
  • 權限控制: 僅允許管理員 IP 或後台登入狀態存取此 Action

注意事項

  • PDO 需安裝 pdo_mysql 擴展
  • 匯出大量資料時可能超過 memory_limit 或 max_execution_time,建議 CLI 模式執行並調整參數
  • 僅適用於 MySQL,其他資料庫需修改 SHOW CREATE 等專用語法
  • 含 BLOB/TEXT 大欄位的表匯出 INSERT 可能極大,需評估可行性

此功能模組化程度高,可直接移植至任何 ThinkPHP 專案,快速擁有資料庫備份下載能力。

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