Я создаю XML-файл с нуля и потребность знать, преобразовывает ли htmlentities () каждый символ, который мог бы потенциально повредить XML-файл (и возможно данные UTF-8)? Значения будут от канала Твиттера/flickr, таким образом, я должен буду быть уверен!
htmlentities()
не является гарантированным способом создания легального XML.
Используйте htmlspecialchars()
вместо htmlentities()
, если вас беспокоит только это. Если у вас есть несоответствия кодировок между представлением ваших данных и кодировкой вашего XML документа, htmlentities()
может послужить для их обхода/прикрытия (при этом размер вашего XML увеличится). Я считаю, что лучше привести кодировки в соответствие и просто использовать htmlspecialchars()
.
Кроме того, имейте в виду, что если вы помещаете возвращаемое значение htmlspecialchars()
внутрь XML-атрибутов, ограниченных одинарными кавычками, вам необходимо передать флаг ENT_QUOTES
, чтобы все одинарные кавычки в вашей исходной строке также были правильно закодированы. Я рекомендую сделать это в любом случае, так как это сделает ваш код невосприимчивым к ошибкам, возникающим в результате использования кем-либо одинарных кавычек для атрибутов XML в будущем.
Редактировать: Для уточнения:
htmlentities()
преобразует ряд не-ANSI символов (я предполагаю, что это то, что вы имеете в виду под данными UTF-8) в сущности (которые представлены только ANSI символами). Однако она не может сделать это для любых символов, у которых нет соответствующей сущности, и поэтому не может гарантировать, что ее возвращаемое значение состоит только из символов ANSI. Вот почему я предлагаю не использовать его.
Если кодировка является возможной проблемой, решайте ее явно (например, с помощью iconv()
).
Правка 2: Улучшенный ответ с учетом комментария Джоша Дэвиса ниже.
Dom :: createTextNode ()
автоматически экранирует ваш контент.
Пример:
$dom = new DOMDocument;
$element = $dom->createElement('Element');
$element->appendChild(
$dom->createTextNode('I am text with Ünicödé & HTML €ntities ©'));
$dom->appendChild($element);
echo $dom->saveXml();
Вывод:
<?xml version="1.0"?>
<Element>I am text with Ünicödé & HTML €ntities ©</Element>
Когда вы устанавливаете внутреннюю кодировку на utf-8, например
$dom->encoding = 'utf-8';
вы все равно получите
<?xml version="1.0" encoding="utf-8"?>
<Element>I am text with Ünicödé & HTML €ntities ©</Element>
Обратите внимание, что приведенное выше не то же самое, что установка второго аргумента $ value
в Dom :: createElement ()
. Метод только проверяет правильность имен ваших элементов. См. Примечания на странице руководства, например
$dom = new DOMDocument;
$element = $dom->createElement('Element', 'I am text with Ünicödé & HTML €ntities ©');
$dom->appendChild($element);
$dom->encoding = 'utf-8';
echo $dom->saveXml();
вызовет предупреждение
Warning: DOMDocument::createElement(): unterminated entity reference HTML €ntities ©
и следующий результат:
<?xml version="1.0" encoding="utf-8"?>
<Element>I am text with Ünicödé </Element>
Итак, ваш вопрос: "Гарантированно ли результат htmlentities () будет соответствовать XML и UTF-8?" Ответ - нет.
htmlspecialchars () должно быть достаточно для экранирования специальных символов XML, но в любом случае вам придется дезинфицировать свои строки UTF-8. Даже если вы создадите свой XML, скажем, с помощью SimpleXML, вам придется дезинфицировать строки. Я не знаю о других библиотеках, таких как XMLWriter или DOM, я думаю, что это то же самое.