什么是“ANSI as UTF-8”,如何使fputcsv()生成带有BOM的UTF-8?

时间:2009-09-04 17:57:12

标签: php utf-8 character-encoding notepad++

我制作了一个PHP脚本,用于生成以前由其他进程生成的CSV文件。 然后,CSV文件必须由另一个进程导入。

导入旧的CSV文件可以正常工作,但是在导入新的CSV文件时会出现特殊字符问题。

当我用Notepad ++打开旧的CSV时,它说编码是UTF-8,当我用它打开新的CSV时,它说它们的编码是'ANSI as UTF-8'。

这两者有什么不同?

我怎样才能使fopen和fputcsv使用'pure?' UTF-8编码?

谢谢!

4 个答案:

答案 0 :(得分:42)

该文件没有任何问题。 “ANSI as UTF-8”意味着没有BOM,但Notepad ++通过分析字节模式明确地将编码识别为UTF-8。我通过创建一个包含俄语,希腊语和波兰语文本的文件并将其保存为UTF-8而没有BOM来测试。这是:

# Russian
Следующая

# Greek
Επόμενη

# Polish
Więcej

我在另一个编辑器(EditPad Pro)中执行了此操作,并使用十六进制模式确保BOM不存在。当我在NPP中打开它时,它显示编码为“ANSI as UTF-8”并且所有字符都正确显示。然后,仍然在十六进制模式下,我删除了第一个俄语字符的第一个字节。当我再次在NPP中打开它时,它将编码显示为“ANSI”,并将文本的非ASCII部分显示为mojibake

; Russian
¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ

; Greek
Επόμενη

; Polish
Więcej

回到EditPad,这次我添加了一个BOM,但没有修复西里尔字符。这次NPP将编码报告为“UTF-8”,除了第一个俄语字符外,所有内容都正确显示,如下所示。 “A1”是应该是UTF-8中该字符的第二个字节的十六进制表示。它以反色方案显示,表示错误。

# Russian
A1ледующая

# Greek
Επόμενη

# Polish
Więcej

总结:在缺少BOM的情况下,Notepad ++会查找不能表示ASCII字符的字节,因为它们的值大于127(或7F hex)。如果它找到任何,但它们都符合UTF-8所需的模式,它会将文件解码为UTF-8,并将状态栏中的编码报告为“ANSI as UTF-8”。

但如果它发现一个字节不符合UTF-8行,它会将文件解码为“ANSI”,这意味着底层平台的默认单字节编码。如果您的文件已损坏,那就是您将看到的内容。

编辑:虽然你的文件在没有它的情况下有效,你可以通过在文件的最开头手动编写三个字节"EF BB BF"来添加一个BOM - 但应该有一个更好的方法。你现在如何生成内容?因为 UTF-8,其中至少有一个非ASCII字符;否则,NPP会将其报告为“ANSI”。

另一种可能的考虑因素:如果您对使用CSV文件的过程有任何影响,也许您可​​以将其配置为期望没有BOM的UTF-8。从技术上讲,任何可以使用 BOM解码UTF-8 而不使用而不使用解码的软件的软件都会损坏。 Unicode联盟实际上不鼓励使用UTF-8 BOM,而不是任何人都在听。

答案 1 :(得分:6)

根据Notepad ++相关的线程herehere,'ANSI as UTF-8'表示没有 BOM的UTF-8 ,而普通的'UTF-8'表示具有BOM的UTF-8。因此,阅读CSV的过程可能需要Byte-order mark才能将CSV正确读取为UTF-8。

但在进入之前,请确保您的脚本实际上写了UTF-8!当您在Notepad ++中打开新的CSV(并将其称为“ANSI as UTF-8”)时,是否正确显示了所有“特殊”字符?如果没有,您需要调整脚本以实际写入UTF-8,如果是,请检查BOM差异。

答案 2 :(得分:1)

尝试将PHP脚本更改为UTF-8。有时必须(尽管可以绕过)将脚本放在数据的相同字符编码中。

类似问题:PHP: Explode using special characters

答案 3 :(得分:0)

值得注意的是,如果您将PHP文件格式化为UTF-8,则ANSI作为UTF-8,即没有BOM的UTF-8非常有用。如果您的PHP文件正在向浏览器输出html,那么BOM将包含在w3c validator明确警告的HTML输出中:

  

在UTF-8文件中找到的字节顺序标记。

     

已知UTF-8编码文件中的Unicode字节顺序标记(BOM)会导致某些文本编辑器和旧版浏览器出现问题。在获得更好的支持之前,您可能需要考虑避免使用它。

除此之外,我发现BOM混淆了Firefox的Firebug,它现在认为你的所有<head>内容实际上都在<body>标签中。