PHP:在不知道原始字符集的情况下将任何字符串转换为UTF-8,或者至少尝试

2022-08-30 06:39:37

我有一个应用程序来处理来自世界各地的客户,当然,我希望进入我数据库中的所有内容都采用UTF-8编码。

对我来说,主要问题是我不知道任何字符串的源将是什么编码 - 它可能来自文本框(仅当用户实际提交表单时才有用),或者它可能来自上传的文本文件,因此我真的无法控制输入。<form accept-charset="utf-8">

我需要的是一个函数或类,以确保进入我数据库中的内容尽可能地进行UTF-8编码。我试过,但这有问题(如果输入是“未婚妻”,则返回“未婚妻”)。我尝试了很多东西=/iconv(mb_detect_encoding($text), "UTF-8", $text);

对于文件上传,我喜欢要求最终用户指定他们使用的编码,并向他们展示输出外观的预览,但这无助于对抗讨厌的黑客(实际上,这可能会使他们的生活更轻松一些)。

我已经阅读了有关该主题的其他Stack Overflow问题,但它们似乎都有细微的差异,例如“我需要解析RSS提要”或“我从网站上抓取数据”(或者,实际上,“你不能”)。

但一定有一些东西至少要好好尝试


答案 1

你所要求的是非常困难的。如果可能,最好让用户指定编码。以这种方式,防止攻击应该不会更容易或更难。

但是,您可以尝试这样做:

iconv(mb_detect_encoding($text, mb_detect_order(), true), "UTF-8", $text);

将其设置为严格可能有助于您获得更好的结果。


答案 2

在祖国俄罗斯,我们有四种流行的编码,所以你的问题在这里有很大的需求。

仅通过符号的字符代码无法检测到编码,因为代码页相交。不同语言的一些代码页甚至具有完全的交集。因此,我们需要另一种方法

使用未知编码的唯一方法是使用概率。因此,我们不想回答“这个文本的编码是什么?”的问题,我们试图理解“这个文本最有可能的编码是什么?”。

在一个流行的俄罗斯科技博客中,有一个人发明了这种方法:

在要支持的每种编码中构建字符代码的概率范围。你可以用你的语言使用一些大文本来构建它(例如,一些小说,使用莎士比亚的英语和托尔斯泰的俄语,LOL)。你会得到这样的东西:

    encoding_1:
    190 => 0.095249209893009,
    222 => 0.095249209893009,
    ...
    encoding_2:
    239 => 0.095249209893009,
    207 => 0.095249209893009,
    ...
    encoding_N:
    charcode => probabilty

接下来,您采用未知编码的文本,对于“概率字典”中的每个编码,您搜索未知编码文本中每个符号的频率。符号的概率求和。使用较大评级进行编码可能是赢家。对于较大的文本,有更好的结果。

顺便说一句,mb_detect_encoding肯定不起作用。是的,一点也不。请看一下“ext/mbstring/libmbfl/mbfl/mbfl_ident.c”中的mb_detect_encoding源代码。


推荐