CSV(Comma-Separated Values)因其結構簡單、跨平台相容性佳,常被用於資料匯入匯出。PHP 內建 fgetcsv() 函式,能高效解析 CSV 格式。本文整理三種常見讀取場景的完整代碼,供開發者直接參考套用。
適用於檔案較小、需對全量資料進行多次處理的情況。
<?php
$file = fopen('data.csv', 'r');
$goods_list = [];
while (($data = fgetcsv($file)) !== FALSE) {
// $data 為索引陣列,對應該行各欄位
$goods_list[] = $data;
}
fclose($file);
// 範例:輸出第 3 筆資料的第 1 欄
echo $goods_list[2][0];
?>
關鍵點: fgetcsv() 會自動處理欄位內含逗號、雙引號、換行符等特殊情況,回傳的陣列可直接使用。
適用於大型 CSV、只需抽取特定行(如標題行、某筆記錄)以節省記憶體。
<?php
function get_csv_line(string $filename, int $line_num): ?array {
$handle = fopen($filename, 'r');
if (!$handle) return null;
$current_line = 0;
while (($data = fgetcsv($handle)) !== FALSE) {
$current_line++;
if ($current_line === $line_num) {
fclose($handle);
return $data;
}
}
fclose($handle);
return null;
}
// 使用範例:讀取第 10 行
$row = get_csv_line('data.csv', 10);
if ($row) {
print_r($row);
} else {
echo "行數超出範圍或檔案讀取失敗";
}
?>
改良說明: 原始碼使用 fgets() 逐行讀取原始字串,再手動分割,易受欄位包含分隔符影響。改用 fgetcsv() 更穩健。
適用於大檔案分批處理、實作分頁顯示。
<?php
function get_csv_range(string $filename, int $start_line, int $end_line): array {
$handle = fopen($filename, 'r');
if (!$handle) return [];
$result = [];
$current_line = 0;
while (($data = fgetcsv($handle)) !== FALSE) {
$current_line++;
if ($current_line < $start_line) continue;
if ($current_line > $end_line) break;
$result[] = $data;
}
fclose($handle);
return $result;
}
// 使用範例:讀取第 11~20 行
$rows = get_csv_range('data.csv', 11, 20);
foreach ($rows as $row) {
echo implode(', ', $row) . "<br>";
}
?>
網路上常見的另兩種讀取模式,供參考:
fgetss() + explode()<?php
$handle = fopen("1.csv", "r");
while (!feof($handle)) {
$buffer = fgetss($handle, 2048); // 移除 HTML/ PHP 標籤
$data = explode(",", $buffer);
print_r($data);
}
fclose($handle);
?>
缺點: 簡單分割無法處理欄位內含逗號、引號、換行的情況,不建議用於正式專案。
fgetcsv() 迴圈(推薦)<?php
$handle = fopen("1.csv", "r");
$row = 1;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
for ($i = 0; $i < $num; $i++) {
echo $data[$i] . " ";
}
echo "<br>";
$row++;
}
fclose($handle);
?>
此寫法最符合 CSV 標準,建議作為預設方案。
iconv() 或 mb_convert_encoding() 轉為 UTF-8