了解PHP的mb_detect_encoding和mb_check_encoding函数的结果

时间:2016-10-07 14:55:11

标签: php character-encoding windows-1252

我正在尝试理解mb_detect_encoding和mb_check_encoding这两个函数的逻辑,但文档很差。从一个非常简单的测试字符串开始

$string = "\x65\x92";

使用Windows-1252编码时,小写'a'后面跟一个曲线引号。

我得到以下结果:

mb_detect_encoding($string,"Windows-1252"); //false
mb_check_encoding($string,"Windows-1252"); //true
mb_detect_encoding($string,"ISO-8859-1"); //ISO-8859-1
mb_check_encoding($string,"ISO-8859-1"); //true
mb_detect_encoding($string,"UTF-8",true); //false
mb_detect_encoding($string,"UTF-8"); //UTF-8
mb_check_encoding($string,"UTF-8"); //false

我不明白为什么detect_encoding为字符串而不是“Windows-1252”提供“ISO-8859-1”,根据https://en.wikipedia.org/wiki/ISO/IEC_8859-1https://en.wikipedia.org/wiki/Windows-1252,字节x92被定义在Windows-1252字符编码中但不在ISO-8859-1中。

其次,我不明白detect_encoding如何返回false,但check_encoding可以为相同的字符串和相同的字符编码返回true。

最后,我不明白为什么每个字符串都可以被检测为UTF-8,严格模式与否。字节x92是UTF-8中的连续字节,但在此字符串中,它跟随有效字符字节,而不是序列的前导字节。

1 个答案:

答案 0 :(得分:0)

您的示例很好地说明了为什么mb_detect_encoding应该谨慎使用,因为它不直观,有时逻辑错误。如果必须使用,始终传递strict = true作为第三个参数(因此非UTF8字符串不会被报告为UTF-8。

按照可能性/优先级的顺序,在所需编码数组上运行mb_check_encoding会更可靠。例如:

$encodings = [
    'UTF-8',
    'Windows-1252',
    'SJIS',
    'ISO-8859-1',
];

$encoding = 'UTF-8';
$string = 'foo';
foreach ($encodings as $encoding) {
    if (mb_check_encoding($string, $encoding)) {
        // We'll assume encoding is $encoding since it's valid
        break;
    }
}

排序取决于您的优先级。