使用 fputcsv() / fgetcsv() 写入 csv 时数据出现乱码

don*_*ote 1 php csv escaping fgetcsv fputcsv

PHP 中的 fputcsv() 和 fgetcsv() 似乎存在编码问题或错误。

以下 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);
Run Code Online (Sandbox Code Playgroud)

给我这个输出:

BEFORE:
array (
  0 => 'A',
  1 => '["a","\\\\","b"]',
  2 => 'B',
)

AFTER:
array (
  0 => 'A',
  1 => '["a","\\\\',
  2 => 'b""]"',
  3 => 'B',
)
Run Code Online (Sandbox Code Playgroud)

很明显,数据在途中被损坏。最初该行只有 3 个单元格,后来该行有 4 个单元格。由于反斜杠也用作转义字符,中间的单元格被分割。

另请参阅 https://3v4l.org/nc1oE 或者此处,使用分隔符、封装、escape_char 的显式值: https: //3v4l.org/Svt7m

在写入 CSV 之前,有什么方法可以清理/转义我的数据,以保证从文件中读取的数据完全相同?

CSV 是完全可逆的格式吗?

编辑:目标是一种正确写入和读取任何 csv 数据的机制,以便在一次往返之后数据仍然相同。

编辑:我意识到我并不真正理解 $escape_char 参数。另请参见fgetcsv/fputcsv $escape 参数从根本上被破坏也许这个问题的答案也将使我们更接近解决方案。

cmb*_*cmb 5

罪魁祸首是 fputcsv() 使用转义字符,这是 CSV 的非标准扩展。(嗯,就 RFC 7111 而言可以被视为标准。)基本上,这个转义字符必须被禁用,但是将空字符串作为 $escape 传递给 fputcsv() 是行不通的。通常,传递 NUL 字符应该会给出所需的结果,但是,请参阅https://3v4l.org/MlluN