PHP函数mb_detect_encoding严格模式

vas*_*123 6 php character-encoding

在函数mb_detect_encoding中有一个严格模式的参数.

在第一个,最受欢迎的评论中:

<?php
$str = 'áéóú'; // ISO-8859-1
mb_detect_encoding($str, 'UTF-8'); // 'UTF-8'
mb_detect_encoding($str, 'UTF-8', true); // false
Run Code Online (Sandbox Code Playgroud)

这是真的,是的.但有人可以给我一个解释,为什么呢?

use*_*918 4

这个答案中的所有内容都是基于我对此处此处代码的阅读。

\n\n

我没有写它,我没有使用调试器单步执行它,这只是我的解释。

\n\n
\n\n

严格模式的目的似乎是检查整个字符串对于编码是否有效,而非严格模式则允许子序列可能是有效字符串的一部分。例如,如果字符串以多字节字符的第一个字节结尾,则它在严格模式下不会匹配,但在非严格模式下仍符合 UTF-8 的资格。

\n\n

然而,似乎存在一个错误*,在非严格模式下,在某些情况下仅检查字符串的第一个字节。

\n\n

例子:

\n\n

0xf8UTF-8 中的任何地方都不允许使用该字节。当放置在字符串的开头时,mb_detect_encoding()无论使用哪种模式,都会正确返回 false。

\n\n
$str = "\\xf8foo";\n\nvar_dump(\n    mb_detect_encoding($str, \'UTF-8\'),      // bool(false)\n    mb_detect_encoding($str, \'UTF-8\', true) // bool(false)\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

但只要前导字节可能出现在 UTF-8 序列中的任何位置,非严格模式就会返回 UTF-8。

\n\n
$str = "foo\\xf8";\n\nvar_dump(\n    mb_detect_encoding($str, \'UTF-8\'),      // string(5) "UTF-8"\n    mb_detect_encoding($str, \'UTF-8\', true) // bool(false)\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

因此,虽然您的 ISO-8859-1 字符串\'\xc3\xa1\xc3\xa9\xc3\xb3\xc3\xba\'不是有效的 UTF-8,但第一个字节"\\xe1"可能会出现在 UTF-8 中,并mb_detect_encoding()错误地返回该字符串。

\n\n
\n\n

*我已在https://bugs.php.net/bug.php?id=72933上为此打开了一份报告

\n