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

PHP 操作 CSV 檔案完整指南:讀寫、編碼處理與大檔案分段讀取

     編輯:PHP 相關知識

前言

CSV (Comma-Separated Values) 是資料交換最通用格式。PHP 內建 fgetcsv()、fputcsv() 等函式,能正確處理欄位包含逗號、引號、換行等複雜情況,比手動 explode() 可靠得多。

一、寫入 CSV:fputcsv()

基本範例

<?php
$list = array(
    'aaa,bbb,ccc,dddd',
    '11,22,33',
    '"php","java"'
);

$fp = fopen('file.csv', 'w');
foreach ($list as $line) {
    fputcsv($fp, explode(',', $line));
}
fclose($fp);
?>

進階:自動處理特殊字元

<?php
$data = [
    ['姓名', '年齡', '備註'],
    ['王小明', 25, '含有"雙引號"和,逗號'],
    ['李大仁', 30, "換行\n測試"],
];

$fp = fopen('export.csv', 'w');
// 寫入 BOM 讓 Excel 正確識別 UTF-8
fwrite($fp, "\xEF\xBB\xBF");
foreach ($data as $row) {
    fputcsv($fp, $row);
}
fclose($fp);
?>

關鍵點:
✅ fputcsv() 自動處理雙引號跳脫、欄位加引號
✅ 寫入 UTF-8 BOM (\xEF\xBB\xBF) 讓 Excel 直接開啟不亂碼
✅ 直接傳入陣列,無需手動組字串

二、讀取 CSV:fgetcsv()

基本逐行讀取

<?php
$row = 1;
$handle = fopen("file.csv", "r");
while ($data = fgetcsv($handle, 1000, ",")) {
    $num = count($data);
    echo "<p> 第 $row 行有 $num 個欄位: <br>\n";
    $row++;
    for ($c = 0; $c < $num; $c++) {
        // 編碼轉換:Big5/GBK → UTF-8
        $data[$c] = iconv("gbk", "utf-8//IGNORE", $data[$c]);
        echo $data[$c] . "<br>\n";
    }
}
fclose($handle);
?>

指定讀取第 N 行

<?php
function get_file_line($file_name, $line_no) {
    $n = 0;
    $handle = fopen($file_name, 'r');
    if ($handle) {
        while (!feof($handle)) {
            ++$n;
            $out = fgets($handle, 4096);
            if ($line_no == $n) break;
        }
        fclose($handle);
    }
    return ($line_no == $n) ? $out : false;
}

echo get_file_line("data.csv", 10);
?>

讀取指定區間 (第 11-20 行)

<?php
function get_file_lines($file_name, $start, $end) {
    $n = 0;
    $lines = [];
    $handle = fopen($file_name, "r");
    if ($handle) {
        while (!feof($handle)) {
            ++$n;
            $out = fgets($handle, 4096);
            if ($start <= $n) $lines[] = $out;
            if ($end == $n) break;
        }
        fclose($handle);
    }
    return ($end == $n) ? $lines : false;
}

$rows = get_file_lines("data.csv", 11, 20);
foreach ($rows as $row) echo $row . "<br>";
?>

三、大檔案處理策略

場景建議做法
超大檔 (GB 級)分塊讀取 + 生成器 yield、或用 Linux split 切分後平行處理
記憶體限制ini_set('memory_limit', '512M')、避免一次載入全部
編碼不確定mb_detect_encoding() 檢測後再 iconv()
異常欄位數檢查 count($data) 一致性、記錄異常行

四、常見編碼問題對照表

來源編碼目標編碼iconv 參數說明
Big5 (繁中)UTF-8iconv("big5", "utf-8//IGNORE", $str)台灣常見
GBK/GB2312 (簡中)UTF-8iconv("gbk", "utf-8//IGNORE", $str)大陸常見
UTF-8 with BOMUTF-8移除 BOM: ltrim($str, "\xEF\xBB\xBF")Excel 匯出常見
SJISUTF-8iconv("sjis-win", "utf-8//IGNORE", $str)日文系統

五、實務建議總結

  1. 永遠用 fgetcsv/fputcsv,不要用 explode/implode
  2. 匯出給 Excel:加 UTF-8 BOM、欄位含中文無需額外處理
  3. 匯入來源不明:先用編輯器確認編碼,再用 iconv 轉換
  4. 大量資料:考慮 SplFileObject 物件導向介面,支援 setCsvControl()
  5. 錯誤處理:fgetcsv() 回傳 false 代表錯誤或 EOF,需嚴格判斷

SplFileObject 現代寫法補充

<?php
$file = new SplFileObject("data.csv");
$file->setFlags(SplFileObject::READ_CSV);
$file->setCsvControl(","); // 分隔符

foreach ($file as $row) {
    // $row 已是陣列
    var_dump($row);
}
?>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved