我编写了一个PHP脚本,生成之前由另一个过程生成的CSV文件。之后,CSV文件必须由另一个进程导入。
旧CSV文件的导入正常工作,但是当导入新的CSV文件时,会出现特殊字符问题。
当我使用Notepad ++打开旧的CSV文件时,它说编码为UTF-8,而当我使用它打开新的CSV文件时,它说它们的编码为“ANSI as UTF-8”。
两者有什么区别?
如何使fopen和fputcsv使用'纯粹的' UTF-8编码?
谢谢!
我编写了一个PHP脚本,生成之前由另一个过程生成的CSV文件。之后,CSV文件必须由另一个进程导入。
旧CSV文件的导入正常工作,但是当导入新的CSV文件时,会出现特殊字符问题。
当我使用Notepad ++打开旧的CSV文件时,它说编码为UTF-8,而当我使用它打开新的CSV文件时,它说它们的编码为“ANSI as UTF-8”。
两者有什么区别?
如何使fopen和fputcsv使用'纯粹的' UTF-8编码?
谢谢!
文件没有问题。"ANSI as UTF-8" 表示没有字节顺序标记,但 Notepad++ 通过分析字节模式明确将编码识别为 UTF-8。我通过创建一个包含俄文、希腊文和波兰文本的文件,并将其保存为没有字节顺序标记的 UTF-8 来测试了这一点。下面是文件:
# Russian
Следующая
# Greek
Επόμενη
# Polish
Więcej
我在另一个编辑器(EditPad Pro)中进行了操作,并使用十六进制模式确保没有BOM。当我在NPP中打开它时,它显示为“ANSI作为UTF-8”编码,并且所有字符都正确显示。然后,仍然在十六进制模式下,我删除了第一个俄语字符的第一个字节。当我再次在NPP中打开它时,它显示为“ANSI”编码,并将文本的非ASCII部分显示为乱码:
; Russian
¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ
; Greek
Επόμενη
; Polish
Więcej
回到EditPad,这次我添加了BOM,但没有修复西里尔字符。 NPP这次报告编码为“UTF-8”,除了第一个俄文字符显示不正确外,其他一切都正常显示,如下所示。“A1”是该字符在UTF-8中应该是第二个字节的十六进制表示。它以反色方案显示,以指示错误。
# Russian
A1ледующая
# Greek
Επόμενη
# Polish
Więcej
总结一下:如果没有BOM(字节顺序标记),Notepad ++会查找不能表示ASCII字符的字节,因为它们的值大于127(或7F
十六进制)。如果找到任何这样的字节,但它们都符合UTF-8所要求的模式,则将文件解码为UTF-8,并在状态栏中报告编码为“ANSI as UTF-8”。
但是,如果它发现了一个不符合UTF-8规则的字节,它会将文件解码为“ANSI”,也就是底层平台的默认单字节编码。如果您的文件已经损坏,那么你看到的就是这种情况。
编辑:尽管您的文件没有BOM也是有效的,但您可以通过手动写入三个字节"EF BB BF"
来添加BOM - 但应该有更好的方法。您现在是如何生成内容的?因为它确实是UTF-8,其中至少有一个非ASCII字符;否则,NPP将其报告为“ANSI”。
另一个需要考虑的可能性是:如果您对消费CSV文件的过程有任何影响力,也许可以将其配置为期望使用没有BOM的UTF-8。从技术上讲,任何能够解码有BOM的UTF-8但不能解码无BOM的UTF-8的软件都是有问题的。 Unicode联盟实际上不赞成使用UTF-8 BOM,尽管似乎没有人在听。
此外,我发现BOM会让Firefox的Firebug混淆,现在它认为所有的在UTF-8文件中找到字节顺序标记。
已知UTF-8编码文件中的Unicode字节顺序标记(BOM)会对某些文本编辑器和旧版浏览器造成问题。您可能希望考虑避免使用它,直到它得到更好的支持。
<head>
内容实际上都在<body>
标签中。