fgetcsv / fputcsv $ escape参数根本崩溃 [英] fgetcsv/fputcsv $escape parameter fundamentally broken

查看:194
本文介绍了fgetcsv / fputcsv $ escape参数根本崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

fgetcsv fputcsv 支持 $ escape 参数,但是,它是坏了,或者我不明白它应该如何工作。忽略您没有看到 fputcsv 中记录的 $ escape 参数的事实,它在PHP源中受支持

fgetcsv and fputcsv support an $escape argument, however, it's either broken, or I'm not understanding how it's supposed to work. Ignore the fact that you don't see the $escape parameter documented on fputcsv, it is supported in the PHP source, there's a small bug preventing it from coming through in the documentation.

该函数还支持 $ delimiter $ enclosure 参数,分别默认为逗号和双引号。我希望 $ escape 参数应该被传递为了有一个字段包含任何一个元字符(反斜杠,逗号或双引号),但是这肯定不是案子。 (我现在从阅读维基百科中可以了解到,这些都应该用双引号括起来)。

The function also supports $delimiter and $enclosure parameters, defaulting to a comma and a double quote respectively. I would expect the $escape parameter should be passed in order to have a field containing any one of those metacharacters (backslash, comma or double quote), however this certainly isn't the case. (I now understand from reading Wikipedia, these are to be enclosed in double-quotes).

例如,在评论部分影响了许多海报的陷阱 fgetcsv 文档。我们希望将一个反斜杠写入字段的情况。

Take for example the pitfall that has affected numerous posters in the comments section from the fgetcsv documentation. The case where we'd like to write a single backslash to a field.

$r = fopen('/tmp/test.csv', 'w');
fwrite($r, '"\"');
fclose($r);

$r = fopen('/tmp/test.csv', 'r');
var_dump(fgetcsv($r));
fclose($r);

这会返回 false 。我也试过\\,但也返回 false 。用一些模糊的文本填充反斜杠给 fgetcsv 需要的提升... hi\\therehi\there都解析并具有相同的结果,但结果只有一个反斜杠,所以 $ escape 在所有?

This returns false. I've also tried "\\", however that also returns false. Padding the backslash(es) with some nebulous text gives fgetcsv the boost it needs... "hi\\there" and "hi\there" both parse and have the same result, but the result has only 1 backslash, so what's the point of the $escape at all?

我没有在双引号中包含反斜杠时观察到相同的行为。写入包含字符串 \ \\ 的'CSV'文件时,解析时具有相同的结果

I've observed the same behavior when not enclosing the backslash in double quotes. Writing a 'CSV' file containing the string \, and \\, have the same result when parsed by fgetcsv, 1 backslash.

让我们来问一下PHP如何编码反斜杠: fgetcsv 作为CSV中的字段使用 fputcsv

Let's ask PHP how it might encode a backslash as a field in a CSV using fputcsv

$r = fopen('/tmp/test.csv', 'w');
fputcsv($r, array('\\'));
fclose($r);
echo file_get_contents('/tmp/test.csv');

结果是双引号单引号反斜杠(我试过3个版本的PHP> 5.5.4当 $ enclose 支持应该添加到 fputcsv )。这样的热闹是 fgetcsv 甚至不能正确地读取我上面的注释,它返回 false .. 。我希望 fputcsv 不要用双引号或 fgetcsv 将反斜杠括起来,以便能够读取\作为 fputcsv 写了...或者真的 fputcsv 可以写入包含反斜杠的双引号和 fgetcsv 能够正确解析它!

The result is a double-quote enclosed single backslash (and I've tried 3 versions of PHP > 5.5.4 when $enclose support was supposedly added to fputcsv). The hilarity of this is that fgetcsv can't even read it properly per my notes above, it returns false... I'd expect fputcsv not to enclose the backslash in double quotes or fgetcsv to be able to read "\" as fputcsv has written it..., or really in my apparently misconstrued mind, for fputcsv to write a double quote enclosed pair of backslashes and for fgetcsv to be able to properly parse it!

尝试使用 fputcsv ,然后通过 fgetcsv 读取。

Try writing a single quote to a file using fputcsv, then reading it via fgetcsv.

$aBackslash = array('\\');

// Write a single backslash to a file using fputcsv
$r = fopen('/tmp/test.csv', 'w');
fputcsv($r, $aBackslash);
fclose($r);

// Read the file using fgetcsv
$r = fopen('/tmp/test.csv', 'r');
$aFgetcsv = fgetcsv($r);
fclose($r);

// Compare the read value from fgetcsv to our original value
if(count(array_diff($aBackslash, $aFgetcsv)))
  echo "PHP CSV support is broken\n";



问题



有一些问题

Questions

Taking a step back I have some questions


  • $ escape 参数有什么意义? >
  • 考虑到CSV文件的宽松定义,可以说PHP正确支持他们吗?

  • 要对CSV文件中的反斜杠进行编码?

  • What's the point of the $escape parameter?
  • Given the loose definition of CSV files, can it be said PHP is supporting them correctly?
  • What's the 'proper' way to encode a backslash in a CSV file?

发现这当一个同事提供了一个从Python生成的CSV文件,它写出一个单引号括起来的双引号和 fgetcsv 无法读取它。我有胆量问他是否可以使用标准 Python函数。我很少知道PHP CSV工具包是一个纠结的混乱! (FWIW:Python dev告诉我他正在使用CSV写入模块)。

I initially discovered this when a co-worker provided me a CSV file produced from Python, which wrote out a single backslash enclosed by double quotes and after fgetcsv failed to read it. I had the gaul to ask him if he could use a standard Python function. Little did I know the PHP CSV toolkit is a tangled mess! (FWIW: the Python dev tells me he's using the CSV writing module).

推荐答案

a href =https://docs.python.org/2/library/csv.html#csv-fmt-params =nofollow> CSV格式参数,在封闭值中使用的转义字符(

From a quick look at Python's documentation on CSV Format Parameters, the escape character used within enclosed values (i.e. inside double quotes) is another double quote.

对于PHP,默认转义字符是反斜杠(^);匹配Python的行为,你需要使用这个:

For PHP, the default escape character is a backslash (^); to match Python's behaviour you need to use this:

$data = fgetcsv($r, 0, ',', '"', '"');

(^)其实 fgetcsv()以相同的方式处理 $ enclosure || $ enclosure $ escape || $ enclosure $ escape 参数用于避免将反斜杠视为特殊字符。

(^) Actually fgetcsv() treats both $enclosure||$enclosure and $escape||$enclosure in the same way, so the $escape argument is used to avoid treating the backslash as a special character.

(^^)将 $ length 参数设置为 0 而不是固定的硬限制会降低效率。 em>

(^^) Setting the $length parameter to 0 instead of a fixed hard limit makes it less efficient.

这篇关于fgetcsv / fputcsv $ escape参数根本崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆