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

PHP 導入 SQL 檔案完整實作:從原理到可復用類庫

     編輯:PHP 相關知識

PHP 導入 SQL 檔案完整實作:從原理到可復用類庫

在專案部署、資料遷移或自動化測試中,常需透過 PHP 程式化方式匯入 .sql 檔案。本文詳解核心思路,並提供一個支援事務、註釋過濾、錯誤回滾的 ImportSql 類,開箱即用。

核心處理流程

  1. 讀取檔案:file_get_contents() 將整個 SQL 載入字串。
  2. 移除註釋:使用正則刪除 -- 單行註釋與 /* */ 多行註釋。
  3. 分割語句:以 ;\n 為界拆分成陣列,並 trim() 去除首尾空白。
  4. 事務執行:開啟事務逐條執行,任一失敗即回滾並拋出錯誤行號。

完整類別程式碼

<?php
/**
 * SQL 匯入工具類
 * 支援:註釋過濾、事務執行、錯誤定位、多語句批次匯入
 */
class ImportSql
{
    /** @var resource 資料庫連接資源 */
    protected $connect = null;
    /** @var bool 資料庫選擇結果 */
    protected $db = null;
    /** @var string 原始 SQL 內容 */
    public $sqlFile = "";
    /** @var array 解析後的 SQL 陣列 */
    public $sqlArr = array();

    /**
     * 建構子:建立資料庫連線
     * @param string $host 主機
     * @param string $user 使用者
     * @param string $pw   密碼
     * @param string $db_name 資料庫名稱
     */
    public function __construct($host, $user, $pw, $db_name)
    {
        $this->connect = mysql_connect($host, $user, $pw)
            or die("連線失敗: " . mysql_error());
        $this->db = mysql_select_db($db_name, $this->connect)
            or die("選擇資料庫失敗: " . mysql_error());
    }

    /**
     * 匯入 SQL 檔案
     * @param string $url 檔案路徑
     * @return bool 成功回傳 true
     */
    public function Import($url)
    {
        if (!file_exists($url)) exit("檔案不存在!");
        $this->sqlFile = file_get_contents($url);
        if (!$this->sqlFile) exit("讀取檔案錯誤!");

        $this->GetSqlArr();
        return $this->RunSql();
    }

    /** 解析 SQL 字串為陣列 */
    public function GetSqlArr()
    {
        $str = $this->sqlFile;
        // 移除單行註釋
        $str = preg_replace('/--.*/i', '', $str);
        // 移除多行註釋
        $str = preg_replace('/\/\*.*\*\/(\;)?/i', '', $str);

        // 分割語句
        $str = explode(";\n", $str);
        foreach ($str as $v) {
            $v = trim($v);
            if (empty($v)) continue;
            $this->sqlArr[] = $v;
        }
    }

    /** 事務執行所有 SQL */
    public function RunSql()
    {
        if (mysql_query('BEGIN')) {
            foreach ($this->sqlArr as $k => $v) {
                if (!mysql_query($v)) {
                    mysql_query('ROLLBACK');
                    exit("SQL 執行錯誤:第 " . $k . " 行 - " . mysql_error());
                }
            }
            mysql_query('COMMIT');
            return true;
        } else {
            exit('無法開啟事務!');
        }
    }
}

// ---------- 使用範例 ----------
header("Content-type:text/html;charset=utf-8");
$sql = new ImportSql("localhost", "root", "", "log_db");
$rst = $sql->Import("./log_db.sql");
if ($rst) echo "匯入成功!";
?>

關鍵細節說明

  • 正則註釋移除:preg_replace('/--.*/i', '', $str) 處理單行;preg_replace('/\/\*.*\*\/(\;)?/i', '', $str) 處理多行,i 忽略大小寫。
  • 分割邊界:採用 ;\n 而非單純 ;,避免誤切預存程序或觸發器內部的分號。
  • 事務保護:確保「全成功或全失敗」,維護資料一致性。
  • 錯誤定位:失敗時輸出具體行號(陣列索引)與 MySQL 錯誤訊息,利於除錯。

現代化建議

上述範例使用已棄用的 mysql_* 函數。實際專案建議改用 PDO 或 mysqli,並採用預處理語句防止注入。核心邏輯(註釋過濾、分割、事務)保持不變,只需替換資料庫操作層即可。


將此類封裝為 Composer 套件或專案共用 Library,即可在部署腳本、單元測試、CI/CD 流程中複用,大幅提升資料庫遷移效率。

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