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

Pet*_*uza 19 php notepad++ utf-8 character-encoding

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

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

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

这两者有什么区别?

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

谢谢!

Ala*_*ore 42

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

# Russian
?????????

# Greek
???????

# Polish
Wi?cej
Run Code Online (Sandbox Code Playgroud)

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

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

; Greek
Επόμενη

; Polish
Więcej
Run Code Online (Sandbox Code Playgroud)

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

# Russian
A1????????

# Greek
???????

# Polish
Wi?cej
Run Code Online (Sandbox Code Playgroud)

总结一下:在没有BOM的情况下,Notepad ++会查找不能表示ASCII字符的字节,因为它们的值大于127(或7F十六进制).如果它找到任何,但它们都符合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 而不是没有 BOM的软件都会被破坏.Unicode Consortium实际上不鼓励使用UTF-8 BOM,而不是任何人都在听.

  • 听起来像Notepad ++,其"ANSI as UTF-8"愚蠢**是唯一的问题 - 如果没有,它做得很好*模糊*问题.但你是对的,我忽略了回答问题的第二部分. (3认同)

Hen*_*pel 6

根据与此处此处的Notepad ++相关的线程,'ANSI as UTF-8'表示没有 BOM的UTF-8 ,而普通的'UTF-8'表示带BOM的UTF-8.因此,读取CSV的过程可能需要字节顺序标记才能将CSV正确读取为UTF-8.

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

  • 现在Notepad ++显示"没有BOM的UTF-8"而不是令人困惑的"ANSI as UTF-8".好转!:) (2认同)