Я пытаюсь понять логику двух функций mb_detect_encoding и mb_check_encoding, но документация плохая. Начиная с очень простой тестовой строки
$string = "\x65\x92";
Это строчная буква «а», за которой следует фигурная кавычка при использовании кодировки Windows-1252.
Я получаю следующие результаты:
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
Я не понимаю, почему Detective_encoding дает «ISO-8859-1» для строки, а не «Windows-1252», когда, согласно https://en.wikipedia.org/wiki/ISO/IEC_8859-1 а также https://en.wikipedia.org/wiki/Windows-1252, байт x92 определен в кодировке символов Windows-1252, но не в ISO-8859-1.
Во-вторых, я не понимаю, как detect_encoding может возвращать false, но check_encoding может возвращать true для той же строки и той же кодировки символов.
Наконец, я не понимаю, почему строку можно определить как UTF-8, строгий режим или нет. Байт x92 является байтом продолжения в UTF-8, но в этой строке он следует за действительным символьным байтом, а не передним байтом последовательности.
Ваши примеры хорошо показывают, почему 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;
}
}
Порядок зависит от ваших приоритетов.
Других решений пока нет …