Wszystko w tej odpowiedzi jest oparte na moim odczycie kodu here i here.
Nie napisałem tego, nie zrobiłem tego za pomocą debuggera, to jest tylko moja interpretacja.
Wydaje się, że zamiar był na tryb ścisły, aby sprawdzić, czy ciąg znaków jako całość była ważna do kodowania, natomiast w trybie non-ścisłe pozwoliłoby na sub-sekwencji może być częścią poprawny ciąg. Na przykład, jeśli ciąg zakończył się tym, co powinno być pierwszym bajtem znaku wielobajtowego, nie pasowałoby to w trybie ścisłym, ale nadal kwalifikuje się jako UTF-8 w trybie nie ścisłym.
Jednak wydaje się, że istnieje błąd *, w którym w trybie nie ścisłym sprawdzany jest tylko pierwszy bajt ciągu znaków.
przykład:
Bajt 0xf8
nie może nigdzie UTF-8.Po umieszczeniu na początku ciągu mb_detect_encoding()
prawidłowo zwraca dla niego wartość false, niezależnie od tego, który tryb jest używany.
$str = "\xf8foo";
var_dump(
mb_detect_encoding($str, 'UTF-8'), // bool(false)
mb_detect_encoding($str, 'UTF-8', true) // bool(false)
);
Ale tak długo, jak długo bajt wiodący może wystąpić w dowolnym miejscu w sekwencji UTF-8, tryb nie ścisły zwraca UTF-8.
$str = "foo\xf8";
var_dump(
mb_detect_encoding($str, 'UTF-8'), // string(5) "UTF-8"
mb_detect_encoding($str, 'UTF-8', true) // bool(false)
);
więc w czasie, gdy ISO-8859-1 ciąg 'áéóú'
jest nieprawidłowy UTF-8, pierwszy bajt "\xe1"
może wystąpić w UTF-8 i mb_detect_encoding()
błędnie zwraca łańcuch jako taki.
* Mam otwarty raport dla tego w https://bugs.php.net/bug.php?id=72933
Ostatecznie że flaga zostanie przeniesione na [tutaj] (https://github.com/php/php-src/blob/ c72282a13b12b7e572469eba7a7ce593d900a8a2/ext/mbstring/libmbfl/mbfl/mbfilter.C# L718); ale niech mnie diabli, jeśli uda mi się rozgryźć, co robi ... – deceze
FWIW, * jeszcze jeden powód, dla którego nie należy nigdy korzystać z tej funkcji, ponieważ * wykrywanie * kodowania jest zasadniczo niemożliwe. Jednak bardzo interesujące pytanie. – deceze
@deceze Funny: jedyny komentarz na temat 'strict' w całym kodzie źródłowym to'/* set strict flag */' –