注意。
存在持续的错误 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
= ",", string $enclosure
= "\"", string $escape
= "\\"): array|false从以 CSV 格式的文件中获取一行,并返回包含读取的字段的数组。
注意:
此函数会考虑区域设置。如果
LC_CTYPE
为例如en_US.UTF-8
,则此函数可能会错误地读取单字节编码的文件。
separator
字段分隔符(仅一个单字节字符)。默认为逗号或使用 SplFileObject::setCsvControl() 设置的值。
enclosure
字段封闭字符(仅一个单字节字符)。默认为双引号或使用 SplFileObject::setCsvControl() 设置的值。
escape
转义字符(最多一个单字节字符)。默认为反斜杠 (\
) 或使用 SplFileObject::setCsvControl() 设置的值。空字符串 (""
) 会禁用专有转义机制。
注意: 通常,字段内的
enclosure
字符通过重复它来转义;但是,escape
字符可以用作替代方案。因此,对于默认参数值,""
和\"
具有相同的含义。除了允许转义enclosure
字符外,escape
字符没有特殊含义;它甚至不打算转义自身。
返回包含读取字段的索引数组,如果出错则返回 false
。
注意:
CSV 文件中的空行将作为包含单个
null
字段的数组返回,除非使用SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE
,在这种情况下空行会被跳过。
版本 | 描述 |
---|---|
7.4.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
注意。
存在持续的错误 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。