___ кодировка в UTF-8 - есть ли конечное решение? - PullRequest
4 голосов
/ 12 июня 2010

Я просматривал Интернет, просматривал SO, документацию PHP и многое другое.

Кажется нелепой проблемой отсутствие стандартного решения. Если вы получили неизвестный набор символов, в котором есть странные символы (например, английские кавычки), существует ли стандартный способ преобразования их в UTF-8?

Я видел много грязных решений, использующих множество функций и проверок, и ни одно из них точно не сработает.

Кто-нибудь придумал свою собственную функцию или решение, которое всегда работает?


EDIT

Многие люди ответили, сказав, что «это не разрешимо» или что-то в этом роде. Я понимаю это сейчас, но никто не дал никакого решения, которое бы работало, кроме utf8_encode, которое очень ограничено. Какие методы существуют для борьбы с этим? Что такое лучший метод?

Ответы [ 4 ]

11 голосов
/ 12 июня 2010

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

Но почему вы сталкиваетесь с неизвестными наборами символов? Для этого нет общего решения, потому что общая проблема не должна существовать в первую очередь. Каждая веб-страница и источник данных могут и должны иметь определение набора символов, а если его нет, следует попросить администратора этого ресурса добавить его.

(Не похоже на умника, но это - единственный способ справиться с этим хорошо.)

9 голосов
/ 14 июня 2010

Причина, по которой вы видели так много сложных решений этой проблемы, заключается в том, что по определению она не разрешима.Процесс кодирования строки текста является недетерминированным.Можно создавать различные комбинации текста и кодировок, которые приводят к одному и тому же потоку байтов.Следовательно, строго говоря логически, невозможно определить кодировку, набор символов и текст из потока байтов.

В действительности, можно достичь результатов, которые "достаточно близки", используя эвристический метод.методы, потому что есть конечный набор кодировок, с которыми вы можете столкнуться в дикой природе, и с достаточно большой выборкой программа может определить наиболее вероятную кодировку.Достаточно ли хороши результаты, зависит от приложения.

Я хочу прокомментировать вопрос о пользовательских данных.Все данные, публикуемые с веб-страницы, имеют известную кодировку (POST поставляется с кодировкой, определенной разработчиком для этой страницы).Если пользователь вставляет текст в поле формы, браузер интерпретирует текст на основе кодировки исходных данных (как это известно в операционной системе) и кодировки страницы и при необходимости перекодирует ее.Слишком поздно обнаружить кодировку на сервере - потому что браузер, возможно, изменил поток байтов на основе предполагаемой кодировки.

Например, если я наберу букву Ä на своей немецкой клавиатуре и опубликую ее на странице в кодировке UTF-8, будет 2 байта (xC3 x84), отправленных на сервер.Это допустимая строка EBCDIC, которая представляет буквы C и d.Это также допустимая строка ANSI, которая представляет 2 символа Ã и „.Однако невозможно, независимо от того, что я пытаюсь, вставить строку в кодировке ANSI в форму браузера и ожидать, что она будет интерпретирована как UTF-8 - потому что операционная система знает, что я вставляю ANSI (я скопировалтекст из Textpad, где я создал текстовый файл в кодировке ANSI) и преобразует его в UTF-8, что приводит к потоку байтов xC3 x83 xE2 x80 x9E.

Моя точка зрения заключается в том, что если пользователю удастся выложить мусорвозможно, потому что он был уже мусором в то время, когда он был вставлен в форму браузера, потому что клиент не имел надлежащей поддержки для набора символов, кодировки, чего угодно.Поскольку кодировка символов не является детерминированной, вы не можете ожидать, что существует тривиальный метод, чтобы раскрыться в такой ситуации.

К сожалению, для загруженных файлов проблема остается.Единственное надежное решение, которое я вижу, состоит в том, чтобы показать пользователю часть файла и спросить, правильно ли он интерпретировался, и циклически перебирать кучу разных кодировок, пока это не так.

Или мы могли бы разработатьэвристический метод, который смотрит на вхождение определенных символов на разных языках.Скажем, я загрузил свой текстовый файл, который содержит два байта xC3 x84.Другой информации нет - всего два байта в файле.Этот метод может обнаружить, что буква Ä довольно распространена в немецком тексте, но буквы Ã и „вместе встречаются редко на любом языке, и, таким образом, определить, что кодировка моего файла действительно UTF-8.Это грубый уровень сложности, с которым приходится сталкиваться такому эвристическому методу, и чем больше статистических и лингвистических фактов он может использовать, тем более достоверными будут его результаты.

1 голос
/ 12 июня 2010

Pekka прав насчет ненадежности, но если вам нужно решение и вы готовы пойти на риск, и у вас есть библиотека mbstring, этот фрагмент должен работать:

function forceToUtf8($string) {
    if (!mb_check_encoding($string)) {
        return false;
    }
    return mb_convert_encoding($string, 'UTF-8', mb_detect_encoding($string));
} 
0 голосов
/ 14 июня 2010

Если я не ошибаюсь, есть нечто, называемое utf8encode ... оно хорошо работает, КРОМЕ этого, если вы уже в utf8

http://php.net/manual/en/function.utf8-encode.php

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...