PHP: кодировка UTF 8 символов - PullRequest
3 голосов
/ 11 августа 2009

Я очищаю список каналов RSS с помощью cURL, а затем читаю и анализирую данные RSS с помощью SimpleXML. Сортированные данные затем вставляются в базу данных mySQL.

Однако, как указано в http://dansays.co.uk/research/MNA/rss.php У меня возникли проблемы с отображением символов неправильно.

Примеры:

âGuitar Hero: Van Halenâ Trailer And Tracklist Available

NV 10/10/09 – Salt Lake City, UT 10/11/09 – Denver, CO 10/13/09 –

Я пытался использовать htmlentities и htmlspecialchars в данных перед их вставкой в ​​базу данных, но, похоже, это не помогло решить проблему.

Как я мог решить эту проблему?

Спасибо за любые советы.

Обновлено

Я попробовал то, что предложил Грег, и проблема все еще здесь ...

Вот код, который я использовал для SET NAMES в PDO:

$dbh = new PDO($dbstring, $username, $password); 

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

$dbh->query('SET NAMES "utf8"');

Я немного повторил с данными simplexml перед их сортировкой и вставкой в ​​базу данных, и теперь я считаю, что это как-то связано с cURL ...

Вот что у меня есть для cURL:

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);

curl_setopt($ch, CURLOPT_HEADER, 0);

curl_setopt($ch, CURLOPT_ENCODING, 'UTF-8');

$data = curl_exec($ch);

curl_close($ch);

$doc = new SimpleXmlElement($data, LIBXML_NOCDATA);

Устранена проблема

Мне пришлось установить кодировку содержимого на странице RSS / HTML на "UTF-8", чтобы решить эту проблему. Я полагаю, что это не совсем исправлено, поскольку проблемы с символами все еще присутствуют в исходных данных. Надеемся на правильную поддержку этого в PHP6!

Ответы [ 4 ]

3 голосов
/ 03 января 2012

Просто краткое замечание о CURLOPT_ENCODING : это заголовок Accept-Encoding , который совсем не совпадает с кодировкой символов. Поддерживаются следующие кодировки приема: «identity», «deflate» и «gzip».

3 голосов
/ 11 августа 2009

Ваша страница обслуживается как UTF-8, поэтому я указал пальцем на базу данных.

Убедитесь, что соединение установлено в UTF-8, прежде чем любые SELECT или INSERTS - в MySQL:

SET NAMES "utf8"
2 голосов
/ 11 августа 2009

Как и все отладки, вы начинаете с изоляции проблемы:

Я очищаю список RSS-каналов с помощью cURL, - посмотрите на XML-файл из RSS-канала, который вызывает проблему (существует более одного канала, поэтому некоторые каналы могут быть правильными и для каналов, которые являются неправильными, чтобы быть неправильным по-разному)

и затем я читаю и анализирую данные RSS с помощью SimpleXML. - распечатываю поле, которое читает SimpleXML, - это нормально или проблема обнаруживается?

Затем отсортированные данные вставляются в базу данных MySQL. - распечатывает шестнадцатеричное (поле), длину (поле) и char_length (поле) для фрагмента данных, который создает проблему.

EDIT

Возьмите корм http://hangout.altsounds.com/external.php?type=RSS2, поместите его в валидатор http://validator.w3.org/feed/. Они объявляют свой тип контента как iso-8859-1, но часть реального контента, такого как кавычки, находится в чем-то вроде cp1252 - например, они используют байт 0x93 для представления левой цитаты - http://www.fileformat.info/info/unicode/char/201C/charset_support.htm.

Что раздражает в этом, так это то, что это не отображается в некоторых инструментах - Firefox, похоже, догадывается, что происходит, и правильно отображает кавычки, а главное, SimpleXML преобразует 0x93 в utf8, поэтому получается 0xc293, что усугубляет проблему.

РЕДАКТИРОВАТЬ 2

Обходное решение для более точного чтения этого канала - заменить «ISO-8859-1» на «Windows-1252» перед переходом на Simple XML. Это не будет работать на 100%, потому что оказывается, что некоторые части подачи находятся в UTF8.

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

1 голос
/ 11 августа 2009

Возможно, это связано с прологом XML, который выглядит так для конкретного канала, с которым вы связаны:

<?xml version="1.0" encoding="ISO-8859-1" ?>

Насколько я знаю, libxml, на котором основан SimpleXML, ищет подобные вещи. Я не уверен насчет XML-файлов, но уверен, что в случае HTML-строк он ищет элементы META, которые определяют кодировку.

Попробуйте удалить пролог XML (однажды я решил похожую проблему, убрав теги HTML META) и не забудьте utf8_encode() данных перед передачей их в SimpleXMLElement.

...