PHP Conference Japan 2024

SplFileObject::fgetcsv

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

SplFileObject::fgetcsv從檔案取得一行並解析為 CSV 欄位

說明

public SplFileObject::fgetcsv(字串 $separator = ",", 字串 $enclosure = "\"", 字串 $escape = "\\"): 陣列|false

從 CSV 格式的檔案中取得一行,並以陣列形式返回讀取的欄位。

注意事項此函式會考慮到地區設定。例如,如果 LC_CTYPEen_US.UTF-8,則某些單一位元組編碼的資料可能會被錯誤地解析。

參數

separator

欄位分隔符號(僅限單一位元組字元)。預設為 , 或先前呼叫 SplFileObject::setCsvControl() 所設定的值。

enclosure

欄位括住字元(僅限單一位元組字元)。預設為 " 或先前呼叫 SplFileObject::setCsvControl() 所設定的值。

escape

跳脫字元(最多一個單一位元組字元)。預設為 \ 或先前呼叫 SplFileObject::setCsvControl() 所設定的值。空字串 ("") 會停用專有的跳脫機制。

注意事項通常在欄位內,enclosure 字元會透過重複自身來跳脫;然而,escape 字元可以作為替代方案。因此,對於預設參數值而言,""\" 具有相同的含義。除了允許跳脫 enclosure 字元之外,escape 字元沒有其他特殊含義;它甚至不 meant to 跳脫自身。

警告

從 PHP 8.4.0 開始,依賴 escape 的預設值已被棄用。需要明確地提供它,可以透過位置參數、具名引數 或呼叫 SplFileObject::setCsvControl() 來設定。

警告

escape 設定為非空字串 ("") 時,可能會導致產生的 CSV 不符合 » RFC 4180 標準,或無法在 PHP CSV 函式中順利往返。 escape 的預設值是 "\\",因此建議明確地將其設定為空字串。預設值將在未來的 PHP 版本中更改,不早於 PHP 9.0。

回傳值

回傳一個包含已讀取欄位的索引陣列,或者在發生錯誤時回傳 false

注意事項:

CSV 檔案中的空白行將會被回傳為一個包含單個 null 欄位的陣列,除非使用 SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE,在這種情況下,空白行會被跳過。

錯誤/例外

如果 separatorenclosure 不是一個位元組長,則會擲出 ValueError

如果 escape 不是一個位元組長或空字串,則會擲出 ValueError

更新日誌

版本 說明
8.4.0 8.4.0 依靠 escape 的預設值現已被棄用。
7.4.0 8.0.0 escape 參數現在也接受空字串以停用專有的跳脫機制。

範例

範例 #1 SplFileObject::fgetcsv() 範例

<?php
$file
= new SplFileObject("data.csv");
while (!
$file->eof()) {
var_dump($file->fgetcsv());
}
?>

範例 #2 SplFileObject::READ_CSV 範例

<?php
$file
= new SplFileObject("animals.csv");
$file->setFlags(SplFileObject::READ_CSV);
foreach (
$file as $row) {
list(
$animal, $class, $legs) = $row;
printf("A %s is a %s with %d legs\n", $animal, $class, $legs);
}
?>

animals.csv 的內容

crocodile,reptile,4
dolphin,mammal,0
duck,bird,2
koala,mammal,4
salmon,fish,0

上述範例將輸出類似以下的內容

A crocodile is a reptile with 4 legs
A dolphin is a mammal with 0 legs
A duck is a bird with 2 legs
A koala is a mammal with 4 legs
A salmon is a fish with 0 legs

參見

新增註解

使用者貢獻的註解 6 則註解

android991 at gmail dot com
5 年前
請注意。
錯誤 46569 仍然存在,它會在使用 SplFileObject::seek() 尋找到非零位置後破壞 SplFileObject::fgetcsv() 的使用,並返回錯誤行的內容 - 差了一行
<?php
$file
= new SplFileObject('foo/bar.csv');
$file->seek(1);
print_r($file->fgetcsv()); // 讀取第 3 行而不是第 2 行
InvisibleSmiley
3 年前
請注意,在 PHP 8.1 之前的版本中,根據給定的 SplFileObject 旗標,此函式可能會返回 NULL 而不是 FALSE。

變更:https://github.com/php/php-src/commit/188b1d4c7c7b3482584e248522d94e06ba616a1c

測試案例:https://3v4l.org/6dQTT
Denitz
6 年前
如果您的 CSV 檔案沒有括住字元的設定,您可能會遇到預設值 " 被識別為資料中括住字元的問題。不允許空的 $enclosure,但您可以使用與 $delimiter 相同的 $enclosure(預設為 \n)來模擬空的括住字元。
v-fpiris at teknober dot com
13 年前
設定分隔符號 '\t' 後,fgetcsv() 會在值為空字串時截斷該值。

解決方法

<?php
$file
= new SplFileObject($path);
$file->setFlags(SplFileObject::DROP_NEW_LINE);
while (
$file->valid()) {
$line = $file->fgets();
$line = explode("\t", $line);

print_r($line);
}
?>
vaughn dot clayton+php at servicetrade dot com
12 年前
請注意,由於 5.3.8 版引入的錯誤 55807 和 61032,如果範例 #2 中的 csv 在每行結尾都有一個換行字元,則 foreach 將會執行 6 次。

迴圈最後一次執行時,$row 將會是 bool(false)。即使使用 SplFileObject::SKIP_EMPTY 和 SplFileObject::DROP_NEW_LINE 也是如此。

在錯誤修復之前,解決方法是在 setFlags() 呼叫中新增 SplFileObject::READ_AHEAD。
jbrauer
4 年前
雖然括住字元不能為 NULL,但您可以將其設定為 ASCII NUL 字元 chr(0),實際效果相同。
To Top