htmlentities() 是否足以创建 xml 安全值?

2022-08-30 12:13:09

我正在从头开始构建一个XML文件,并且需要知道htmlentities()是否转换了可能破坏XML文件(以及可能的UTF-8数据)的每个字符?

这些值将来自twitter / flickr feed,所以我需要确定 -


答案 1

htmlentities() 不是构建合法 XML 的有保证的方式。

使用htmlspecialchars()而不是如果这是你所担心的。如果数据的表示形式和 XML 文档的编码之间存在编码不匹配,则可能有助于解决/掩盖它们(这样做会使 XML 大小膨胀)。我相信最好让你的编码保持一致,只使用.htmlentities()htmlentities()htmlspecialchars()

另外,请注意,如果抽取用单引号分隔的 XML 内部属性的返回值,则还需要传递该标志,以便对源字符串中的任何单引号进行正确编码。无论如何,我建议这样做,因为它可以使您的代码免受将来某人使用单引号作为XML属性而导致的错误的影响。htmlspecialchars()ENT_QUOTES

编辑:澄清:

htmlentities()将许多非 ANSI 字符(我假设这就是 UTF-8 数据的含义)转换为实体(仅用 ANSI 字符表示)。但是,对于没有相应实体的任何字符,它都不能这样做,因此不能保证其返回值仅由 ANSI 字符组成。这就是为什么我建议不要使用它。

如果编码是一个可能的问题,请显式处理它(例如,使用 iconv())。

编辑2:考虑到Josh Davis的评论,改进了答案。


答案 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 &#xDC;nic&#xF6;d&#xE9; &amp; HTML &#x20AC;ntities &#xA9;</Element>

当您将内部编码设置为 utf-8 时,例如

$dom->encoding = 'utf-8';

你仍然会得到

<?xml version="1.0" encoding="utf-8"?>
<Element>I am text with Ünicödé &amp; HTML €ntities ©</Element>

请注意,上述内容与在 Dom::createElement() 中设置第二个参数不同。该方法将仅确保您的元素名称有效。请参阅手册页上的注释,例如$value

$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>

推荐