19

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

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

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

两者有什么区别?

我怎样才能让 fopen 和 fputcsv 使用“纯”?UTF-8 编码?

谢谢!

4

4 回答 4

42

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

# Russian
Следующая

# Greek
Επόμενη

# Polish
Więcej

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

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

; Greek
Επόμενη

; Polish
Więcej

回到 EditPad,这次我添加了 BOM,但没有修复 Cyrillic 字符。这次 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"但应该有更好的方法。您现在如何生成内容?因为它UTF-8,在某处至少有一个非 ASCII 字符;否则,NPP 会将其报告为“ANSI”。

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

于 2009-09-05T03:56:07.637 回答
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 差异。

于 2009-09-04T18:11:24.453 回答
1

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

类似问题:PHP: Explode using special characters

于 2009-09-04T18:04:14.250 回答
0

值得注意的是,ANSI 为 UTF-8,即没有 BOM 的 UTF-8,如果您将 PHP 文件格式化为 UTF-8,则很有用。如果您的 PHP 文件将 html 输出到浏览器,则 BOM 包含在 HTML 输出中,w3c 验证器明确警告:

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

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

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

于 2012-03-06T22:14:59.120 回答