Если вы хотите вывести UTF-8 с DOMDocument, вам нужно указать это.Просто, не правда ли?Если вы уже поняли хитрый вопрос, вы не слишком далеки от этого, но на первый взгляд, это действительно просто.
Рассмотрим следующий (кодированный в UTF-8) пример кода, который выводит шестнадцатеричные сущности:
$dom = new DOMDocument();
$dom->loadXml('<root>ירושלים</root>');
$dom->save('php://output');
Вывод:
<?xml version="1.0"?>
<root>ירושלים</root>
Как написано, если вы хотите вывести это как UTF-8, вам нужно указать его, и это просто:
...
$dom->encoding = 'UTF-8';
$dom->save('php://output');
Выходные данные в явном виде в UTF-8 :
<?xml version="1.0" encoding="UTF-8"?>
<root>ירושלים</root>
Так много для прямой части.Если вас интересуют грязные мелочи, вы можете читать дальше - если нет, пожалуйста, не спрашивайте «почему?» :).
Я только что написал "в UTF-8 явно", поскольку и в первом примере выходные данные кодируются в UTF-8, XML просто содержит шестнадцатеричные сущности, что совершенно правильно - даже в UTF-8!
Вы уже заметили, что я начинаю с придирки, но помните: UTF-8 - это кодировка по умолчанию XML .
И если вы сейчас начнете говорить: эй, подождите, если кодировка по умолчанию UTF-8 в любом случае, почему PHP DOMDocument использует сущности в первую очередь?
Ну, правда, это не вопреки выводу в вопросе.Не всегда .
См. Следующий пример, в котором вместо значения узла, содержащего буквы Ivrit, используется XML-комментарий:
$dom = new DOMDocument();
$dom->loadXml('<root><!-- ירושלים --></root>');
$dom->save('php://output');
Вывод:
<?xml version="1.0"?>
<root><!-- ירושלים --></root>
Хорошо, всеЧисто?Итак, маленький грязный секрет здесь: есть ли у вас эти сущности XML или нет - для документа это не имеет значения, это просто другая форма записи одних и тех же символьных данных XML.И вы уже чувствуете себя приглашенным: давайте попробуем CDATA вместо первого примера:
$dom = new DOMDocument();
$dom->loadXML("<root><![CDATA[ירושלים]]></root>");
$dom->save('php://output');
Вывод:
<?xml version="1.0"?>
<root><![CDATA[ירושלים]]></root>
Как это видно из XML-комментарияНапример, здесь нет никаких сущностей XML, используемых здесь.Ну, они все равно не будут действительными, как в примере с XML-комментариями.
Для обзора давайте создадим пример, который содержит все это:
$dom = new DOMDocument();
$dom->loadXML("<!-- ירושלים --><root>ירושלים <![CDATA[ירושלים]]></root>");
$dom->save('php://output');
Вывод:
<?xml version="1.0"?>
<!-- ירושלים -->
<root>ירושלים <![CDATA[ירושלים]]></root>
Извлеченные уроки:
- UTF-8 всегда используется.Только некоторые объекты используются в PCDATA, если не указана кодировка UTF-8. Если указано другое кодирование UTF-8, применяются другие правила .
- Вы не можете указать, хотите ли вы использовать сущности или нет для вывода, загружая anXML-документ в виде строки в кодировке UTF-8 в PHP DOMDocument per se.Даже с libxml flags и без предоставления спецификации. [1]
- Вы можете указать, что не хотите использовать объекты, установив кодировку документов в UTF-8.
- Если вы можете, вы можете манипулироватьвходная строка, имеющая XML-декларацию с указанием документов, кодирующих , как указано в ответе Гордона .
Совет: Есливаша строка имеет XML-декларацию, которая не соответствует кодировке строк, или вы хотите изменить либо до загрузки строки в DOMDocument вам нужно изменить XML-декларацию и / или повторно-кодировать строку.Это было рассмотрено в ответе на вопрос PHP XMLReader, получите версию и кодировку , продемонстрировав, как работает XMLRecoder
класс .
И это все, надеюсь.
[1] Возможно, если вы загружаете из HTTP-запроса и предоставляете контекст потока и помечаете кодировку символов через метаданные- но это надо сначала проверить, я не знаю.То, что спецификация не работает, является признаком того, что все эти вещи не работают.