如何在 PHP 中解析 csv 在列中具有多行数据
Posted
技术标签:
【中文标题】如何在 PHP 中解析 csv 在列中具有多行数据【英文标题】:How to parse csv in PHP having multiline data in a column 【发布时间】:2011-06-11 14:27:48 【问题描述】:考虑像这样的 CSV 文件
item1,"description 1"
item2,"description 2"
item3,"description 3
description 3 continues on new line"
item4,"description 4"
应该这样解析
item1,"description 1"
item2,"description 2"
item3,"description 3 description 3 continues on new line"
item4,"description 4"
有没有办法在 php 中解析这个具有多行值的 CSV?
【问题讨论】:
@goreSplatter,或者只使用现有的。 @Bart 抱歉,我遗漏了另一个明显的解决方案。 parse csv file php 的可能重复项 【参考方案1】:这里有一些工作示例如何做到这一点。我正在使用 fgetcsv:
字符串变量 $CsvString 中的 CSV:
$fp = tmpfile();
fwrite($fp, $CsvString);
rewind($fp); //rewind to process CSV
while (($row = fgetcsv($fp, 0)) !== FALSE)
print_r($row);
文件中的CSV:
if (($handle = fopen("test.csv", "r")) !== FALSE)
while (($row = fgetcsv($handle, 0, ",")) !== FALSE)
print_r($row);
fclose($handle);
【讨论】:
优秀的答案。我有用户上传的带有 \r 行结尾的 CSV(我不知道为什么),并且必须在解析 CSV 之前进行 strreplace。由于 str_getcsv 不处理多行,并且某些行中包含新行,因此这(虽然 hackish,将内容放在临时文件中只是为了让 PHP 解析它)可以工作。【参考方案2】:fgetcsv
应该能够正确解析这个。
无论如何,我不建议手动执行此操作,在解析 CSV 时有很多这样的陷阱。
【讨论】:
问题是我使用 fgets 从文件中读取行,然后使用 str_getcsv 来解析字符串,而不是仅使用 fgetcsv。它适用于单行列,但不适用于多行列。甚至强硬的 PHP.net 说 fgetcsv“从文件中获取行”似乎这里的“行”不是纯文本文件中的实际行,而是包含所有多行数据的整个实际行。 我今天遇到了同样的问题并做了一点test,这证明了你关于 lines 指的是 csv-rows 而不是到实际的 file-lines. 我希望使用str_getcsv
,因为它不必将整个文件加载到内存中,只需将红色行加载。 fgetcsv
确实适用于多行 CSV 字段,但 str_getcsv
显然不适用。
@Erfan fgetcsv
也一次只从打开的文件句柄中读取一行...!?【参考方案3】:
基于StanleyD 答案,但使用临时内存块(而不是写入磁盘)以获得更好的性能:
$fp = fopen('php://temp','r+');
fwrite($fp, $CsvString);
rewind($fp); //rewind to process CSV
while (($row = fgetcsv($fp, 0)) !== FALSE)
print_r($row);
【讨论】:
【参考方案4】:这是一个使用 PHP 函数str_getcsv()
的快速简便的解决方案
这是一个例子:
function parse_csv( $filename_or_text, $delimiter=',', $enclosure='"', $linebreak="\n" )
$return = array();
if(false !== ($csv = (filter_var($filename_or_text, FILTER_VALIDATE_URL) ? file_get_contents($filename_or_text) : $filename_or_text)))
$csv = trim($csv);
$csv = mb_convert_encoding($csv, 'UTF-16LE');
foreach(str_getcsv($csv, $linebreak, $enclosure) as $row)
$col = str_getcsv($row, $delimiter, $enclosure);
$col = array_map('trim', $col);
$return[] = $col;
else
throw new \Exception('Can not open the file.');
$return = false;
return $return;
想象一下,您需要一个同时处理 URL 和逗号分隔文本的函数。这正是这样工作的功能。只需插入一个 CSV URL 或逗号分隔的文本,它就可以很好地工作。
【讨论】:
没有多行,见@Erfan以上是关于如何在 PHP 中解析 csv 在列中具有多行数据的主要内容,如果未能解决你的问题,请参考以下文章