請注意。
錯誤 46569 仍然存在,它會在使用 SplFileObject::seek() 尋找到非零位置後破壞 SplFileObject::fgetcsv() 的使用,並返回錯誤行的內容 - 差了一行
<?php
$file = new SplFileObject('foo/bar.csv');
$file->seek(1);
print_r($file->fgetcsv()); // 讀取第 3 行而不是第 2 行
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
SplFileObject::fgetcsv — 從檔案取得一行並解析為 CSV 欄位
$separator
= ",", 字串 $enclosure
= "\"", 字串 $escape
= "\\"): 陣列|false從 CSV 格式的檔案中取得一行,並以陣列形式返回讀取的欄位。
注意事項:此函式會考慮到地區設定。例如,如果
LC_CTYPE
為en_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
,在這種情況下,空白行會被跳過。
版本 | 說明 |
---|---|
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
SplFileObject::READ_CSV
請注意。
錯誤 46569 仍然存在,它會在使用 SplFileObject::seek() 尋找到非零位置後破壞 SplFileObject::fgetcsv() 的使用,並返回錯誤行的內容 - 差了一行
<?php
$file = new SplFileObject('foo/bar.csv');
$file->seek(1);
print_r($file->fgetcsv()); // 讀取第 3 行而不是第 2 行
請注意,在 PHP 8.1 之前的版本中,根據給定的 SplFileObject 旗標,此函式可能會返回 NULL 而不是 FALSE。
變更:https://github.com/php/php-src/commit/188b1d4c7c7b3482584e248522d94e06ba616a1c
測試案例:https://3v4l.org/6dQTT
如果您的 CSV 檔案沒有括住字元的設定,您可能會遇到預設值 " 被識別為資料中括住字元的問題。不允許空的 $enclosure,但您可以使用與 $delimiter 相同的 $enclosure(預設為 \n)來模擬空的括住字元。
設定分隔符號 '\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);
}
?>
請注意,由於 5.3.8 版引入的錯誤 55807 和 61032,如果範例 #2 中的 csv 在每行結尾都有一個換行字元,則 foreach 將會執行 6 次。
迴圈最後一次執行時,$row 將會是 bool(false)。即使使用 SplFileObject::SKIP_EMPTY 和 SplFileObject::DROP_NEW_LINE 也是如此。
在錯誤修復之前,解決方法是在 setFlags() 呼叫中新增 SplFileObject::READ_AHEAD。