核心函數速覽
| 函數 | 用途 | 回傳值 |
fputcsv($handle, $fields, $delimiter=',', $enclosure='"', $escape='\\') | 將陣列寫入 CSV 格式到檔案指標 | 寫入位元組數,失敗 false |
fgetcsv($handle, $length=0, $delimiter=',', $enclosure='"', $escape='\\') | 從檔案指標讀取一行並解析為陣列 | 陣列,EOF/錯誤 false |
寫入 CSV 範例
1. 直接寫入檔案
<?php
$data = [
['111', 'sdfsd', 'sdds', '43344', 'rrrr'],
['sssssssss', 'gdfgfd', '232323', 'wwewe', 'dsfds'],
// ...
];
$fp = fopen('test.csv', 'w');
foreach ($data as $row) {
if (fputcsv($fp, $row) === false) {
die("寫入失敗");
}
}
fclose($fp);
2. 寫入字串變數(下載響應)
<?php
ob_start();
$fp = fopen('php://output', 'w');
foreach ($data as $row) fputcsv($fp, $row);
fclose($fp);
$csv = ob_get_clean();
// 直接輸出下載
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="export.csv"');
echo $csv;
讀取 CSV 範例
<?php
$fp = fopen('test.csv', 'r');
echo '<table border="1">';
while (($row = fgetcsv($fp)) !== false) {
echo '<tr>';
foreach ($row as $i => $cell) {
$bg = ($i % 2 === 0) ? '#ccc' : '#999';
echo "<td style='background:$bg'>" . htmlspecialchars($cell) . "</td>";
}
echo '</tr>';
}
echo '</table>';
fclose($fp);
進階主題
編碼問題(中文亂碼)
- Excel 開啟 CSV 預設用系統編碼(繁中 Big5/CP950,簡中 GBK)。
- PHP 產出 UTF-8 時,Excel 可能誤判。解決:輸出 BOM
echo "\xEF\xBB\xBF"; 或轉 iconv('UTF-8', 'CP950//IGNORE', $csv)。
- 讀取時若來源非 UTF-8,用
iconv 轉碼後再 fgetcsv。
大檔案流式處理(記憶體友善)
<?php
// 讀取超大 CSV,逐行處理,不載入整個檔案
$fp = fopen('huge.csv', 'r');
while (($row = fgetcsv($fp, 10000)) !== false) { // length 設大於最長行
// 處理 $row...
}
fclose($fp);
自定義分隔符與包圍字元
// 歐洲常用分號分隔、雙引號包圍
fputcsv($fp, $row, ';', '"', '\\');
fgetcsv($fp, 0, ';', '"', '\\');
常見陷阱
| 陷阱 | 解決 |
| 欄位包含換行符 | fputcsv 會自動用 enclosure 包圍,fgetcsv 正確解析多行欄位。 |
| 欄位包含 enclosure 字元 | 自動轉義(預設 \\),讀取時還原。 |
PHP 5.3- fgetcsv 不支援 $escape 參數 | 升級 PHP 或自行實現解析器。 |
Windows 換行 \r\n 導致最後欄位帶 \r | 開啟檔案用 'r' 模式(自動轉換),或 stream_filter_append($fp, 'convert.line endings')。 |
替代方案
- League\Csv:功能豐富、支援迭代器、轉換器、驗證器,Composer 安裝
league/csv。
- SplFileObject:
new SplFileObject('file.csv'); $obj->setFlags(SplFileObject::READ_CSV); foreach($obj as $row)...
- PHP 內建
str_getcsv():解析單行字串,不涉及檔案指標。
總結
fputcsv/fgetcsv 是 PHP 处理 CSV 的基石,輕量、無依賴、記憶體效率高。掌握編碼轉換、大檔流式讀寫、自定義分隔符,即可應對 90% 匯入匯出需求。複雜報表建議改用 League\Csv 或直接產出 Excel (PhpSpreadsheet)。