在直接文件上传PHP上检测字符编码


Detecting char encoding on direct file uploads PHP

在我的网站上,我允许直接上传文本文件。这些文件然后存储在服务器上,并显示在网站上。我在网站上使用UTF-8。

现在我遇到了麻烦,当人们上传非UTF-8文件包含特殊字符,如é

我一直在做一些测试。制作了2个文本文件,都包含相同的字fiancée。一个编码UTF-8,一个编码ISO 8859-2。

UTF-8版本上传得很好,并正确显示文本,但ISO 8859-2显示为fianc�e

现在我试着用mb_detect_encoding检测上传的文件内容,但无论我扔给它什么文件,它总是检测UTF-8。

我注意到我可以使用utf8_encode将ISO 8859-2文件转换为有效的UTF-8,但这只适用于非utf文件。由于我目前无法检测非utf文件,因此无法使用utf8_encode函数,因为它会混淆有效的UTF-8文件。

希望这是有意义的:)

所以我的问题是,我怎么能检测文件,肯定不是UTF-8编码开始,这样我就可以使用utf8_encode函数对他们。

不能。欢迎学习编码。

严肃地说,文件只是二进制blobs。文件中的位和字节可以表示任何;它可以是图像、CAD数据或者文本。这取决于如何解释字节。对于文本文件,具体表示使用哪种编码来解释它们。文件本身并没有告诉您正确的编码,您必须知道。通常,您希望从文件附带的元数据中了解它。在随机用户上传的情况下,没有元数据,并且/或者它不可靠。所以你不能 "知道"。

下一步是猜测,但这显然不是万无一失的。您可以排除某些编码,例如,如果一个文件没有被验证为UTF-8 (mb_check_encoding($data, 'UTF-8') == false),那么它就不能是UTF-8。但是,任何单字节编码都将被验证为任何其他单字节编码。通过这种方式无法区分ISO-8859-1和ISO-8859-2,字节在两者中都是同等有效的。只是出现的角色可能不是你想要的。为了自动检测,您需要一个统计语言分析器,它可以告诉您这个字符可能不应该出现在那个单词中,以使其符合语法。显然,要做到这一点,您需要知道文件中使用的语言,或者您需要首先检测,即使这样,也很难万无一失。

最理智的方法是询问用户。接受上传,也许做一些可以排除哪些编码的预先测试,然后询问用户文件是在一堆可能的编码中。向他们展示结果,即文件被解释为所选编码时的样子,让用户确认它看起来是正确的。当您打开编码不明确的文件时,许多不错的文本编辑器都会这样做。