Aym*_*Dev 2 php csv byte-order-mark character-encoding utf-16le
我正在尝试使用 PHP 解析 CSV 文件。
该文件对包含逗号的字段使用逗号作为分隔符和双引号,如:
foo,"bar, baz",foo2
Run Code Online (Sandbox Code Playgroud)
我面临的问题是我得到包含逗号分隔的字段。我得到:
"2rue du ..."而不是:2, rue du ...。
编码:
该文件似乎不是 UTF8。它在开头有奇怪的字符(显然不是 BOM,当从 ASCII 转换为 UTF8: 时看起来像这样ÿþ)并且不显示重音。
mb_detect_encoding()的CSV行返回ASCII但它无法转换:
mb_convert_encoding()转换自ASCII但返回亚洲字符自UTF-16LEiconv()返回说明:的iconv():错误的字符集,从转换UTF-16LE/ASCII到UTF8不允许。解析:
我尝试使用以下方法解析此单行(请参阅这 2 条评论)str_getcsv():
$csv = array_map('str_getcsv', file($file['tmp_name']));
Run Code Online (Sandbox Code Playgroud)
然后我尝试fgetcsv():
$f = fopen($file['tmp_name'], 'r');
while (($l = fgetcsv($f)) !== false) {
$arr[] = $l;
}
$f = fclose($f);
Run Code Online (Sandbox Code Playgroud)
在这两种方式中,我都将地址字段分为两部分。但是当我尝试这个代码示例时,我得到了正确解析的字段:
$str = 'foo,"bar, baz",foo2,azerty,"ban, bal",doe';
$data = str_getcsv($str);
echo '<pre>' . print_r($data, true) . '</pre>';
Run Code Online (Sandbox Code Playgroud)
总结一下问题:
UTF-16 LE并在开头不显示奇怪的字符)我终于自己解决了:
我将文件发送到返回UTF16LE 的在线编码检测网站。在检查什么是UTF16LE 之后,它说它有BOM (Byte Order Mark)。
我之前的尝试是使用file()which 返回一个文件行的数组并使用fopen()which 返回一个资源,但我们仍然逐行解析。
我想到了关于转换整个文件(一次每一行)而不是分别转换每一行的工作解决方案。这是一个有效的解决方案:
$f = file_get_contents($file['tmp_name']); // Get the whole file as string
$f = mb_convert_encoding($f, 'UTF8', 'UTF-16LE'); // Convert the file to UTF8
$f = preg_split("/\R/", $f); // Split it by line breaks
$f = array_map('str_getcsv', $f); // Parse lines as CSV data
Run Code Online (Sandbox Code Playgroud)
我不再使用内部逗号分隔地址字段。