我在使用PHP从CSV文件中读取unicode字符时遇到了问题。
以下是UNICODE csv文件的屏幕截图。
我使用的PHP代码如下。
$delimiter = ",";
$row = 1;
$handle = fopen($filePath, "r");
while (($data = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
$num = count($data);
$row++;
for ($c=0; $c < $num; $c++) {
echo $data[$c];
}
}
fclose($handle);
对于上面的代码,我在chrome浏览器中得到以下输出。它有垃圾字符。
但是如果我在echo语句中添加换行符,如下所示,它会给出正确的输出。
echo $data[$c]."\n";
为什么它会像这样?我不想附加这样的换行符。
答案 0 :(得分:2)
UNICODE csv文件。
Windows称为“Unicode”的编码(误导性地; Unicode不是编码)实际上是UTF-16LE。这是一个每个代码单位的双字节编码,因此ASCII字符作为ASCII字节后跟一个零字节。
PHP fgetcsv
函数不支持UTF-16 CSV,它只支持ASCII兼容的编码。它在每个字节0x0A(换行符)和0x2C(逗号)上分割,但在UTF-16LE中,换行符和逗号分别是双字节序列,0x0A 0x00和0x2C 0x00。这意味着你在每个字段的前面获得前导单个0x00字节但是第一个,当一个值包含0x0A或0x2C字节而不是UTF-16编码的换行符/逗号的一部分时,你得到错误的分裂。
当你打印出UTF-16LE编码输出时,额外的0x00字节将每个字段与最后一个字节对齐,这意味着查看它的浏览器看到交替字段不对齐和打印由一个字符的前导字节组成的无意义字符和前一个字符的跟踪字节。
所以你可以做两件事:
如果您有任何选择,请避免使用UTF-16。因为它不兼容ASCII,所以它打破了许多期望的工具。通常最好的编码是UTF-8,它可以包含所有字符,但仍然是ASCII超集......遗憾的是Excel拒绝直接以UTF-8保存CSV文件。
使用一些了解UTF-16的其他CSV解析器。无论如何,避免使用PHP的CSV功能是一个好主意,因为它们做了与标准CSV不匹配的奇怪事情(尽管有一个标准......至少它没有&#39; t匹配RFC 4180和Excel生成的内容。
答案 1 :(得分:0)
尝试在显示文字之前添加此内容
header('Content-Type: text/html; charset=utf-8');
$delimiter = ",";
$row = 1;
$handle = fopen($filePath, "r");
while (($data = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
$num = count($data);
$row++;
for ($c=0; $c < $num; $c++) {
echo $data[$c];
}
}
fclose($handle);