Обнаружение правильной кодировки символов в PHP?

Я пытаюсь определить кодировку строки, но не могу получить правильный результат.
Например:

$str = "€ ‚ ƒ „ …" ;
$str = mb_convert_encoding($str, 'Windows-1252' ,'HTML-ENTITIES') ;
// Now $str should be a Windows-1252-encoded string.
// Let's detect its encoding:
echo mb_detect_encoding($str,'Windows-1252, ISO-8859-1, UTF-8') ;

Этот код выводит ISO-8859-1 но это должно быть Windows-1252,

Что с этим не так?

РЕДАКТИРОВАТЬ:
Обновленный пример, в ответ на @raina77ow.

$str = "€‚ƒ„…" ; // no white-spaces
$str = mb_convert_encoding($str, 'Windows-1252' ,'HTML-ENTITIES') ;
$str = "Hello $str" ; // let's add some ascii characters
echo mb_detect_encoding($str,'Windows-1252, ISO-8859-1, UTF-8') ;

Я снова получаю неправильный результат.

2 ответа

Проблема с Windows-1252 в PHP состоит в том, что он почти никогда не будет обнаружен, потому что, как только ваш текст содержит какие-либо символы за пределами от 0x80 до 0x9f, он не будет обнаружен как Windows-1252.

Это означает, что если ваша строка содержит обычную букву ASCII, например "A", или даже пробел, PHP скажет, что это недопустимая Windows-1252, и, в вашем случае, вернитесь к следующей возможной кодировке, которая является ISO 8859-1. Это ошибка PHP, см. https://bugs.php.net/bug.php?id=64667.

Хотя строки, закодированные с помощью ISO-8859-1 и CP-1252, имеют различное представление байт-кода:

<?php
$str = "&euro; &sbquo; &fnof; &bdquo; &hellip;" ;
foreach (array('Windows-1252', 'ISO-8859-1') as $encoding)
{
    $new = mb_convert_encoding($str, $encoding, 'HTML-ENTITIES');
    printf('%15s: %s detected: %10s explicitly: %10s',
        $encoding,
        implode('', array_map(function($x) { return dechex(ord($x)); }, str_split($new))),
        mb_detect_encoding($new),
        mb_detect_encoding($new, array('ISO-8859-1', 'Windows-1252'))
    );
    echo PHP_EOL;
}

Результаты:

Windows-1252: 802082208320842085 detected:            explicitly: ISO-8859-1
  ISO-8859-1: 3f203f203f203f203f detected:      ASCII explicitly: ISO-8859-1

... из того, что мы видим здесь, похоже, что есть проблема со вторым параметром mb_detect_encoding, С помощью mb_detect_order вместо параметра выдает очень похожие результаты.

Другие вопросы по тегам