Php 使用URL更新DOMAttr值会导致参数丢失,除非使用htmlentities()。为什么?

Php 使用URL更新DOMAttr值会导致参数丢失,除非使用htmlentities()。为什么?,php,domdocument,domxpath,Php,Domdocument,Domxpath,我试图修改包含HTML的字符串中的链接,但发现修改后的URL缺少参数 例如: $html = ' <p> <a href="http://example.com?foo=bar&bar=foobar">Example 1</a> </p>'; libxml_use_internal_errors(true); $dom = new \DOMDocument(); $dom->loadHTML($html); $xpath =

我试图修改包含HTML的字符串中的链接,但发现修改后的URL缺少参数

例如:

$html = '
<p>
    <a href="http://example.com?foo=bar&bar=foobar">Example 1</a>
</p>';

libxml_use_internal_errors(true);
$dom = new \DOMDocument();
$dom->loadHTML($html);
$xpath = new \DOMXPath($dom);

foreach ($xpath->query('//a/@href') as $node) {
    echo '$node->nodeValue: ' . $node->nodeValue . PHP_EOL;
    $newValue = 'http://example2.com?foo=bar&bar=foobar';
    echo '$newValue: ' . $newValue . PHP_EOL;
    $node->nodeValue = $newValue;
    echo '$node->nodeValue: ' . $node->nodeValue . PHP_EOL;
}
如您所见,第二个参数在更新
nodeValue
后丢失

在进行实验时,我尝试将
$newValue
更改为:

$newValue = htmlentities('http://example2.com?foo=bar&bar=foobar');
然后输出变成:

$node->nodeValue: http://example.com?foo=bar&bar=foobar
$newValue: http://example2.com?foo=bar&amp;bar=foobar
$node->nodeValue: http://example2.com?foo=bar&bar=foobar

为什么需要通过
htmlentities()
运行新节点值?

符号是XML/HTML中的保留字符-它们开始字符引用。如果您试图将它们直接写入DOM中的字符串,事情往往会爆炸,因为DOM不知道您想说什么。当您首先使用
htmlentities()
时,它会对“&”进行编码,并且每个人都会再次使用相同的语言

幸运的是,根本不需要
htmlentities()
。不要直接设置
节点值
,而是使用href所有者的方法


而不是: 使用:
在DOM中直接操作字符串可能会导致一些问题,这些问题甚至不一定会在系统中表现出来。在您的示例中,我没有丢失参数,而是丢失了整个URL

我强烈建议尽可能坚持二传

$node->nodeValue: http://example.com?foo=bar&bar=foobar
$newValue: http://example2.com?foo=bar&amp;bar=foobar
$node->nodeValue: http://example2.com?foo=bar&bar=foobar
$node->nodeValue = $newValue;
$node->ownerElement->setAttribute('href', $newValue);