Обнаружение, сохранение, вывод UTF8 с помощью PHP

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

У меня есть база данных mysql DEFAULT CHARACTER UTF-8, мои таблицы имеют параметры сортировки utf8_general_ci

Я использую php-скрипт для чтения данных из RSS-канала, а затем сохраняю эти данные в базе данных. Прежде чем сохранить эти данные, я проверяю, являются ли эти данные UTF-8 или нет, выполнив следующие действия:

protected function _convertToUTF8($content) {
    $enc = mb_detect_encoding($content);
    return mb_convert_encoding($content, "UTF-8", $enc);
}

При выводе этих данных на веб-страницу я устанавливаю заголовки в php

header("Content-type: text/html; charset=utf-8");

и я также установил метатег Content-Type в utf-8

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

Пока что все работает так, как ожидалось, я не получаю забавных символов, и все идет гладко, но должен ли я что-то менять/учитывать при работе с этими данными?

Проблема, с которой я сейчас сталкиваюсь, заключается в выводе этих данных в файл txt (csv). Я использую fwrite(), который успешно создал файл, но третья сторона, которой я передаю этот файл, говорит, что файл не является UTF-8. Я не уверен, что данные выводятся в формате UTF-8, как я могу это проверить? При входе на удаленный сервер через SSH и просмотре файла я получаю Itâs a, когда я просматриваю файл, я получаю Itâ~@~Ys, когда я удаляю файл, я получаю It<E2><80><99>s. Что я здесь упускаю?

Заранее спасибо!


person Lizard    schedule 13.06.2011    source источник
comment
может ли быть спецификация в файле, на который он жалуется? или, может быть, он хочет спецификацию в файле? Я знаю, что у меня были проблемы с этим (не в этом конкретном приложении) раньше, и мне пришлось повторно сохранить файл (в utf-8) без спецификации, чтобы заставить его работать правильно.   -  person kinakuta    schedule 14.06.2011
comment
да, но, надеюсь, я ясно объяснил и получил хороший ответ, который поможет людям в будущем, так как почтовые вопросы были расплывчатыми и обычно относились к выводу, а не к сохранению данных.   -  person Lizard    schedule 14.06.2011
comment
например, см. этот пост о редакторе, который неправильно интерпретирует файл как utf-8 без спецификации: stackoverflow.com/questions/2558172/   -  person kinakuta    schedule 14.06.2011
comment
Этот вопрос требует мнений и фактов об общем процессе, а не об отдельной ошибке.   -  person Lizard    schedule 14.06.2011
comment
У вас есть известное мнение об этом в моем ответе здесь и очень общий намек на весь процесс;)   -  person hakre    schedule 14.06.2011


Ответы (2)


Вы не можете определить кодировку каких-либо данных. Кодировка — это всегда метаинформация рядом с самими данными.

Даже если mb_detect_encoding() пытается сделать это наилучшим образом, вы никогда не должны использовать его для автоматической обработки данных. Потому что, поскольку невозможно определить кодировку из самих данных, эта функция также не может.

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

Как я могу так сказать? Просто пример: текст может быть правильно закодирован в US-ASCII, и процедура обнаружения для UTF-8 вернет, что он действителен в кодировке UTF-8. И это только один пример. Правда в том, что это просто намного сложнее.

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

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

В вашем случае хранения данных из RSS-каналов ищите информацию либо в заголовках ответов, либо в прологе XML. Обычно он содержит кодировку документа в нотации ISO.

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

person hakre    schedule 13.06.2011

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

person Lizard    schedule 29.06.2011