首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

PHP 實現 CSV/TXT 文字檔高效匯入 MySQL 資料表完整範例

     編輯:MySQL 資料庫相關知識

場景與資料格式

適用於結構固定、欄位以逗號分隔的純文字檔(CSV)。範例資料:

aaa,bbb,ccc,ddd,eee
fff,ggg,hhh,iii,jjj,kkk

完整 PHP 匯入腳本

<?php
// load_csv.php
$host     = 'localhost';
$user     = 'db_user';
$pass     = 'db_pass';
$dbname   = 'target_db';
$filePath = '/path/to/data.csv';  // 絕對路徑
$table    = 'import_table';
$delimiter = ',';
$batchSize = 500;  // 批次提交大小

// 1. 建立連線(mysqli 物件導向)
$mysqli = new mysqli($host, $user, $pass, $dbname);
if ($mysqli->connect_errno) {
    die("Connect failed: " . $mysqli->connect_error);
}
$mysqli->set_charset('utf8mb4');

// 2. 開啟檔案
$handle = fopen($filePath, 'r');
if (!$handle) {
    die("Cannot open file: $filePath");
}

// 3. 準備預處理語句(防注入、效能佳)
$placeholders = str_repeat('?,', 5);  // 假設 5 欄位
$placeholders = rtrim($placeholders, ',');
$stmt = $mysqli->prepare("INSERT INTO `$table` (col1,col2,col3,col4,col5) VALUES ($placeholders)");
if (!$stmt) {
    die("Prepare failed: " . $mysqli->error);
}

// 綁定參數(動態綁定陣列)
$bindParams = [];
$bindTypes  = str_repeat('s', 5);  // 全視為字串,或依實際型別調整
$rowCount = 0;

$mysqli->autocommit(false);  // 開啟交易

while (($data = fgetcsv($handle, 0, $delimiter)) !== false) {
    // 欄位數檢查
    if (count($data) !== 5) {
        error_log("Skip invalid row: " . implode(',', $data));
        continue;
    }

    // 綁定變數參考
    $bindParams = [];
    foreach ($data as $i => $val) {
        $bindParams[$i] = $val;
    }
    // 重新綁定(mysqli 需傳參考)
    $refs = [];
    foreach ($bindParams as $key => $val) {
        $refs[$key] = &$bindParams[$key];
    }
    call_user_func_array([$stmt, 'bind_param'], array_merge([$bindTypes], $refs));

    $stmt->execute();
    $rowCount++;

    // 批次提交
    if ($rowCount % $batchSize === 0) {
        $mysqli->commit();
        $mysqli->autocommit(false);
        echo "Committed $rowCount rows...\n";
    }
}

$mysqli->commit();  // 提交剩餘
fclose($handle);
$stmt->close();
$mysqli->close();

echo "Import completed. Total rows: $rowCount\n";
?>

關鍵優化點解析

  1. Prepared Statement:SQL 解析一次,重複執行,防注入。
  2. 批次交易提交:每 500 筆 Commit 一次,大幅減少 I/O 等待。
  3. fgetcsv():內建處理引號、換行、逗號轉義,比 explode() 健壯。
  4. 記憶體友善:逐行讀取,不將整檔載入記憶體,支援 GB 級大檔。
  5. 錯誤容忍:跳過欄位數不符的行並記錄日誌。

進階替代方案

  • LOAD DATA INFILE:MySQL 原生指令,速度最快(需 FILE 權限、檔案在 Server 端):
    LOAD DATA INFILE '/path/data.csv'
    INTO TABLE import_table
    FIELDS TERMINATED BY ',' ENCLOSED BY '"'
    LINES TERMINATED BY '\n'
    IGNORE 1 LINES;
  • ETL 工具:DataX、Kettle、Airflow 適合企業級定時同步。

根據資料量與基礎設施選擇最適方案,PHP 腳本適合中小檔、無 Server 檔案存取權限的場景。

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