php's mb_detect_encoding () - PullRequest
       26

php's mb_detect_encoding ()

4 голосов
/ 17 ноября 2011

Прежде всего я хотел бы сказать, что я прочитал другой пост, касающийся phb's mb_detect_encoding на Странное поведение mb_detect_order () в PHP . Который определенно подтверждает то, что я изучил бы путем следа и ошибки. однако есть еще несколько вещей, которые меня смущают.

Я создаю html-скребки в основном английских сайтов, которые собирают данные и сохраняют их в формате UTF-8 XML. Я столкнулся с проблемой, когда страница самостоятельно объявляет кодировку ISO-8859-1, но она содержит символы, уникальные для Windows-1252. конкретно правильная одинарная кавычка (’) 0x92 Насколько я понимаю, windows-1252 - это расширенный набор iso-8859-1, который заставляет меня задуматься, зачем вообще использовать utf8_encode ()? почему бы просто не использовать iconv ('Windows-1252', 'UTF-8', $ str) вместо utf8_encode (), поскольку все, что представлено в iso-8859-1, будет преобразовано так же, как и символы, уникальные для windows-1252 ( т.е.. € ‚ƒ ''“ ”)

Также

$ansi = "€";//euro mark, the code file itself is in ansi

$detected = mb_detect_encoding($ansi, "WINDOWS-1252");// $detected == "Windows-1252"
$detected = mb_detect_encoding('a'.$ansi, "WINDOWS-1252");// $detected == FALSE
$detected = mb_detect_encoding($ansi.'a', "WINDOWS-1252");// $detected == "Windows-1252"
$detected = mb_detect_encoding($ansi.'a', "WINDOWS-1252",TRUE);// $detected == FALSE

почему это происходит? если первый символ в строке не Windows-1252, хотя остальная часть, это не так? Разве это поведение не делает его довольно бесполезным? насколько различать iso-8859-1 и windows-1252

другое, что меня смутило, скажем, я хочу обнаружить кодировку между ASCII, ISO-8859-1, windows-1252, UTF-8. Можно ли обнаружить строки таким способом, который дает мне самый низкий набор рейтинга? (т.е.

$ascii = "123"; // desired detect result == 'ASCII'
$iso = "é".$ascii; // desired detect result == 'ISO-8859-1'
$ansi = "€".$iso; // desired detect result == 'Windows-1252'
$utf8 = file_get_contents('utf8.txt', true);//$utf8 == '你好123é€', desired detect result == 'UTF-8'

не должен указывать мой массив $ detect_order = («ASCII», «ISO-8859-1», «Windows-1252», «UTF-8»); Я знаю, что это неверно, так как это дало мне следующие результаты

$ascii == 'ASCII'
$iso   == 'ISO-8859-1'
$ansi  == 'ISO-8859-1'
$utf8  == 'ISO-8859-1'

почему мой порядок обнаружения ('ASCII', 'ISO-8859-1', 'Windows-1252', 'UTF-8') неверен для того, что я хочу получить?

ближайшее полученное мной возвращаемое значение было

$ascii == 'ASCII'
$iso   == 'ISO-8859-1'
$ansi  == 'ISO-8859-1'
$utf8  == 'UTF-8'

оба следующих массива mb_detect_order дали мне вышеуказанные значения

$detect_order = array('ASCII', 'UTF-8', 'Windows-1252', 'ISO-8859-1');
$detect_order = array('ASCII', 'UTF-8', 'ISO-8859-1', 'Windows-1252');

это сбивает меня с толку!

фу, кто-то может пролить свет на это? спасибо большое оценил!

Ответы [ 3 ]

2 голосов
/ 12 июня 2014

Это известная ошибка .

Windows-1251 и Windows-1252 будут успешными, только если все Строка состоит из старших байтов символов в определенном диапазоне. Это означает вы никогда не получите правильное преобразование, потому что текст будет выглядеть как ISO-8859-1, даже если это Windows-1252.

Я столкнулся с этой проблемой, конвертируя из LATIN1 в UTF-8. У меня было много содержимого, вставленного из Microsoft Word и сохраненного в поле VARCHAR с использованием кодировки LATIN1 таблицы MySQL. Как вы, наверное, знаете, Word преобразует апострофы и кавычки в умные апострофы и кавычки. Ни один из них не будет отображаться на экране, потому что эти символы не были должным образом преобразованы. Текст всегда обозначался как ISO-8859-1. Чтобы решить эту проблему, я принудительно преобразовал Windows-1252 в UTF-8, и оба апострофы и кавычки (и другие символы) были правильно преобразованы.

1 голос
/ 17 ноября 2011

Не уверен, что я отвечу на все ваши вопросы, но здесь мы идем:

Насколько я понимаю, windows-1252 - это расширенный набор iso-8859-1, который заставляет меня задуматься, зачем вообще использовать utf8_encode ()? почему бы просто не использовать iconv ('Windows-1252', 'UTF-8', $ str) вместо utf8_encode (), поскольку все, что представлено в iso-8859-1, будет преобразовано, а также символы, уникальные для windows-1252

Вы не должны беспокоиться о ut8_encode. Перейдите в iconv () или mb_convert_encoding. ut8_encode преобразует только ISO-8859-1 в UTF-8. если вам нужно конвертировать разные кодировки, используйте другие функции.

По отношению к евро. Не уверен, что это было добавлено (официально или неофициально) к ISO-8859-1 в какой-то момент, но оба приведенных ниже утверждения возвращают true

$ansi = "€";//euro mark, the code file itself is in ansi

$detected = mb_detect_encoding($ansi, "WINDOWS-1252", TRUE);// $detected == "Windows-1252"
echo $detected."<br/>-<br/>";
$detected = mb_detect_encoding($ansi, "ISO-8859-1", TRUE);// $detected == ISO-8859-1
echo $detected."<br/>-<br/>";


$detected = mb_detect_encoding($ansi, "WINDOWS-1252");// $detected == "Windows-1252"
echo $detected."<br/>-<br/>";
$detected = mb_detect_encoding($ansi, "ISO-8859-1");// $detected == ISO-8859-1
echo $detected."<br/>-<br/>";

Обратите внимание, это результат со строгим значением True или False. Это может объяснить, почему

не должен указывать мой массив $ detect_order = («ASCII», «ISO-8859-1», «Windows-1252», «UTF-8»); Я знаю, что это неверно, так как это дало мне следующие результаты

дает вам ISO-8859-1. Я заметил, что вы переключили UTF-8, опередив ISO в последнем порядке, и поэтому он дал вам UTF-8 в конце.

почему мой порядок обнаружения ('ASCII', 'ISO-8859-1', 'Windows-1252', 'UTF-8') неверен для того, что я хочу получить?

Для сайта php http://us3.php.net/manual/en/function.mb-detect-order.php, установка ISO до того, как UTF-8 всегда будет возвращать ISO. Проверьте их бесполезный пример заказа обнаружения.

Из того, что я видел, кажется, что если у вас есть ISO-8859-1 и Windows-1252, вы получите ISO обратно. Если вы возьмете одно или другое, вы получите то, что осталось от двух. Таким образом, расположение последних 2 ниже не имеет значения

$ detect_order = array ('ASCII', 'UTF-8', 'Windows-1252', 'ISO-8859-1'); $ detect_order = array ('ASCII', 'UTF-8', 'ISO-8859-1', 'Windows-1252');

0 голосов
/ 22 декабря 2012

символ € не является частью кодировки utf8!

Вы должны указать его как €!

или кодировать в windows-1252 или iso-8859-15 (то же самое, что и iso-8859-1, но имеет символ €)

...