【发布时间】:2017-06-08 06:13:07
【问题描述】:
使用 fputcsv() 和 fgetcsv() 在 PHP 中似乎存在编码问题或错误。
以下PHP代码:
$row_before = ['A', json_encode(['a', '\\', 'b']), 'B'];
print "\nBEFORE:\n";
var_export($row_before);
print "\n";
$fh = fopen($file = 'php://temp', 'rb+');
fputcsv($fh, $row_before);
rewind($fh);
$row_after = fgetcsv($fh);
print "\nAFTER:\n";
var_export($row_after);
print "\n\n";
fclose($fh);
给我这个输出:
BEFORE:
array (
0 => 'A',
1 => '["a","\\\\","b"]',
2 => 'B',
)
AFTER:
array (
0 => 'A',
1 => '["a","\\\\',
2 => 'b""]"',
3 => 'B',
)
很明显,数据在途中损坏了。最初该行只有 3 个单元格,后来该行有 4 个单元格。由于反斜杠也用作转义字符,中间单元格被拆分。
另请参阅 https://3v4l.org/nc1oE 或者在这里,为 delimiter、enclosure、escape_char 提供明确的值:https://3v4l.org/Svt7m
有什么方法可以在写入 CSV 之前清理/转义我的数据,以确保从文件中读取的数据完全相同?
CSV 是一种完全可逆的格式吗?
编辑:目标是一种将任何数据正确写入和读取为 csv 的机制,以便在一次往返后数据仍然相同。
编辑:我意识到我并不真正了解 $escape_char 参数。另请参阅 fgetcsv/fputcsv $escape parameter fundamentally broken 或许对此的回答也会让我们更接近解决方案。
【问题讨论】:
-
CSV 有很多限制,从嵌入式引号到多行数据。这就是使用 XML、JSON 和各种其他格式的原因。
-
我在导出到 CSV 的数据中有大量嵌入的引号和换行符,直到现在从来没有出现过(可见的)问题。
-
CSV 数据中带有换行符是不可移植的,如果您只想为自己的应用程序提供数据,为什么还要使用 CSV 并编写您想要的任何旧格式 - 并且您使用各种分隔符- 你正在有效地做到这一点。
-
1.取决于应用程序。例如。 LibreOffice Calc 对此没有任何问题。它可能是非标准的,但世界不在乎。 2. 因为原生支持 CSV(或 PHP 风格的 CSV),所以 3. 我主要使用标准分隔符。我使用不同分隔符的唯一原因是测试 PHP 的行为是否会有所不同。
-
另外,我正在开发的应用程序已经有来自外部来源的各种 CSV,所以我更喜欢坚持这种格式而不是发明新格式。
标签: php csv escaping fgetcsv fputcsv