通用和干净的UTF-8编码(PHP)


Universal and clean UTF-8 encoding (PHP)

我希望能够从任何字符集转换为干净的UTF-8在一个调用(我们使用PHP)。

用于Apache Solr索引;问题是Solr使用的(用Java编写的)XML解析器在遇到非法的UTF-8时抛出异常。

我们尝试了iconv(),但它有时会在Warning之后剪辑字符串,丢失一些数据,即使启用了//TRANSLIT和/或//IGNORE

utf8_encode()只对latin1有效。

我们正在使用许多编码从许多来源导入许多文档,我们需要一个完全干净的UTF-8输出。我们不关心时间/资源问题。

谢谢你明智的回答!

  • 您可以尝试使用mb_convert_encodingmb_detect_encoding代替。
  • 在导入这些文档时,您应该真的需要一个内容编码或其他东西。如果您从web建立索引,请查找内容类型标头和实际HTML文件的内容。总是使用这个作为你的主要来源-也许会回到检测,但是检测实际上只是猜测
  • 如果这两个选项没有帮助,我建议编写自己的代码来检测流中的无效字符。然后用iconv()代替这些。

iconv在错误后不继续的原因很简单:在一些字符编码中,正确读取字节很重要,因为字符可能基于多个字节。UTF-8通过使用位掩码来检测字符何时完成来补偿这一点,但并非所有编码都具有此功能。在这样的编码中,单个字节出错意味着字符串的其余部分可能会乱码,这不是您想要的。(我不完全确定,但您应该能够通过获取UTF-16字符串并删除文件中的第五个字节来复制此操作)

嘿,我甚至会说明这个问题:-)下面是一个(有点)UTF-16的例子,每个字符使用2字节。

[74 00] [65 00] [73 00] [74 00] = test

现在让我们删除一个字节——这里是第一个0x00

[74 65] [00 73] [00 74] [00] = ....

我不知道它实际上会变成什么,但正如你所看到的,它只是在缺少一个字节的时候分解字符串的其余部分。如果你够幸运的话,你的索引是中文的