为了账号安全,请及时绑定邮箱和手机立即绑定

为什么这两个 DOMDocument 函数的行为不同?

为什么这两个 DOMDocument 函数的行为不同?

PHP
MMTTMM 2022-08-19 16:05:39
这里建议有两种方法可以获取 DOMDocument 节点的外部 HTML:如何返回 DOMDocument 的外部 html?我感兴趣的是为什么他们似乎以不同的方式对待HTML实体。例:function outerHTML($node) {    $doc = new DOMDocument();    $doc->appendChild($doc->importNode($node, true));    return $doc->saveHTML();}$html = '<p>ACME&rsquo;s 27&rdquo; Monitor is $200.</p>';$dom = new DOMDocument();@$dom->loadHTML($html);$el = $dom->getElementsByTagname('p')->item(0);echo $el->ownerDocument->saveHtml($el) . PHP_EOL;echo outerHTML($el) . PHP_EOL;输出:<p>ACME’s 27” Monitor is $200.</p><p>ACME&rsquo;s 27&rdquo; Monitor is $200.</p>这两种方法都使用 saveHTML(),但由于某种原因,该函数在最终输出中保留了 html 实体,而直接使用节点上下文调用则不会。谁能解释一下为什么 - 最好有某种权威的参考?saveHTML()
查看完整描述

1 回答

?
呼唤远方

TA贡献1856条经验 获得超11个赞

归根结底,这比上面的测试用例还要简单:


<?php

$html = '<p>ACME&rsquo;s 27&rdquo; Monitor is $200.</p>';

$dom = new DOMDocument();

@$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);


echo $dom->saveHtml($dom->documentElement) . PHP_EOL;

echo $dom->saveHtml() . PHP_EOL;

那么问题来了,为什么在保存整个文档而不仅仅是一个特定的节点时,行为会有所不同?DomDocument::saveHtml

通过查看PHP源代码,我们会发现它是使用单个节点还是整个文档进行检查。对于前者,调用该函数时,编码显式设置为 null。对于后者,使用函数,编码不作为此函数的参数包含在内。htmlNodeDumpFormatOutputhtmlDocDumpMemoryFormat

这两个函数都来自 libxml2 库。查看源,我们可以看到尝试检测文档编码,并在找不到文档编码时将其显式设置为ASCII / HTML。htmlDocDumpMemoryFormat

这两个函数最终都调用htmlNodeListDumpOutput,并为其传递已确定的编码;null ( 不会导致编码 – 或 ASCII/HTML – 使用 HTML 实体进行编码。

我的猜测是,对于文档片段或单个节点,编码被认为不如完整文档重要。


查看完整回答
反对 回复 2022-08-19
  • 1 回答
  • 0 关注
  • 108 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信