2013-04-05 10 views
4

Я пытаюсь обнаружить кодировку символов строки, но я не могу получить правильный результат.
Например:Определение правильной кодировки символов в 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.

Что случилось с этим?

EDIT:
Обновлен пример, в ответ на @ 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') ; 

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

+0

Какая версия PHP вы используете? Он правильно показывает здесь http://codepad.viper-7.com/NfvdWm. Кстати, вы всегда должны сначала перечислять UTF-8, потому что это самый ограниченный. ISO-8859-1, вероятно, вообще не требуется, поскольку что-то действительно соответствует ISO-8859-1. – Esailija

+0

@ Esailija, вы не использовали код любого из двух примеров в вопросе. Попробуйте любой из двух примеров, и вы получите результат 'ISO-8859-1'. – GetFree

ответ

0

Хотя строки, закодированные с помощью 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 вместо параметра дает очень похожие результаты.

+0

Символы в примере не существуют в ISO-8859-1. – GetFree

+0

Первая соответствующая кодировка в моем списке - 'Windows-1252'. 'ISO-8859-1' является вторым в списке. – GetFree

+1

@GetFree php строки - это не символы, а байты. Любая строка PHP действительна 'ISO-8859-1', потому что любой байт имеет значение ISO-8859-1. – Esailija

1

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

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