PHP DOMDocument nodeValue сбрасывает литеральные символы UTF-8 вместо закодированных - PullRequest
4 голосов
/ 03 марта 2011

У меня возникла проблема, похожая на этот вопрос :

nodeValue из DomDocument, возвращающий странные символы в PHP

Первопричину, которую я обнаружил, можно имитировать с помощью mb_convert_encoding ()

В моих модульных тестах это, наконец, уловило проблему:

$test = mb_convert_encoding('é', "UTF-8");
$this->assertTrue(mb_check_encoding($test,'UTF-8'),'data is UTF-8');
$this->assertTrue($this->rw->checkEncoding($test,'UTF-8'),'data is UTF-8');
$this->assertIdentical($test,html_entity_decode('é',ENT_QUOTES,'UTF-8'),'values match');

Похоже, что исходное значение данных UTF-8 подходит, и базовая кодовая страница системы, на которой работает PHP, скорее всего, не UTF-8.

До синтаксического анализа (с реализацией HTML5lib, которая создает дамп DOMDocument) строки остаются чистыми, UTF-8 дружественными. Только в точке извлечения данных с использованием

$span->nodeValue

вижу ли я ошибку в стабильности кодирования.

Я предполагаю, что улов htmlentities для экспорта domdocument в nodeValue использует конвертер кодирования, но игнорирует значение встроенной кодировки.

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

UPDATE

Во имя продвижения вперед я переключился с HTML5lib и DOMDocument на Простой HTML DOM , и он экспортирует полностью экранированный html, который затем я могу проанализировать в правильных сущностях UTF-8.

Кроме того, одна функция, которую я не пробовал, была

utf8_decode

Так что это может быть решением для всех, кто столкнулся с этой проблемой. Это решило связанную с этим проблему, с которой я столкнулся при работе с AJAX / PHP. Решение, найденное в этом сообщении в блоге за 2009 год: Преодоление ограничения кодировки AJaX UTF-8 (в PHP)

Ответы [ 2 ]

2 голосов
/ 03 мая 2012

Просто использовал utf8_decode для nodeValue, и он действительно работал, имел проблему с неправильным отображением специальных символов.

Однако некоторые символы по-прежнему остаются проблематичными, например, простая цитата и некоторые другие (например,)

Таким образом, использование $ element-> nodeValue не будет работать, но utf8_decode ($ element-> nodeValue) будет - PARTLY.

1 голос
/ 03 мая 2012

Функции utf8_decode и utf8_encode не очень хорошо названы. Они буквально конвертируются из utf-8 в iso-8859-1 и из iso-8859-1 в utf-8 соответственно.

mb_convert_encoding при вызове только с utf-8 в качестве аргумента, как правило, будет аналогично использованию функции utf8_encode. ( Обычно , если вы не изменили внутреннюю кодовую страницу, чего вы, вероятно, - надеюсь, не сделали).

Большинство функций PHP ожидают, что строки будут iso-8859-1 закодированы. Однако libxml (которая является базовой библиотекой библиотек php для разбора xml) ожидает, что строки будут utf-8. Таким образом, вы можете легко получить искаженные кодировки, если не будете осторожны.

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

Надеюсь, это прояснит немного.

...