Can';t使用php domdocument追加img元素

Can';t使用php domdocument追加img元素,php,domdocument,Php,Domdocument,我在尝试使用php DomDocument将image元素附加到noscript元素时遇到了一个奇怪的问题 如果我创建了一个新的div节点,我可以将其附加到noscript元素,而不会产生任何问题,但是一旦尝试附加image元素,脚本就会超时 我做错了什么 <?php $html = '<!DOCTYPE html><html><head><title>Sample</title></head><body>

我在尝试使用php DomDocument将image元素附加到noscript元素时遇到了一个奇怪的问题

如果我创建了一个新的div节点,我可以将其附加到noscript元素,而不会产生任何问题,但是一旦尝试附加image元素,脚本就会超时

我做错了什么

<?php

$html = '<!DOCTYPE html><html><head><title>Sample</title></head><body><img src="https://example.com/images/example.jpg"></body></html>';

$doc = new DOMDocument();
$doc->loadHTML($html);

$images = $doc->getElementsByTagName('img');

foreach ($images as $image) {
    $src = $image->getAttribute('src');
    $noscript = $doc->createElement('noscript');

    $node = $doc->createElement('div');
    //$node = $doc->createElement('img'); If a uncomment this line the script just times out

    $node->setAttribute('src', $src);

    $noscript->appendChild($node);

    $image->setAttribute('x-data-src', $src);
    $image->removeAttribute('src');
    $image->parentNode->appendChild($noscript);
    //$image->parentNode->appendChild($newImage);
}
$body = $doc->saveHTML();

echo $body;

您陷入了一个递归循环。这将帮助你想象发生了什么。为了清晰起见,我添加了缩进:

php > $html = '<!DOCTYPE html><html><head><title>Sample</title></head><body><img src="https://example.com/images/example.jpg"></body></html>';
php > 
php > $doc = new DOMDocument();
php > $doc->loadHTML($html);
php > 
php > $images = $doc->getElementsByTagName('img');
php > 
php > $count=0;
php > foreach ($images as $image) {
php {     $count++;
php {     if($count>4) {
php {         die('limit exceeded'); 
php {     }
php { 
php {     $src = $image->getAttribute('src');
php {     $noscript = $doc->createElement('noscript');
php { 
php {     //$node = $doc->createElement('div');
php {     $node = $doc->createElement('img'); //If a uncomment this line the script just times out
php { 
php {     $node->setAttribute('src', $src);
php { 
php {     $noscript->appendChild($node);
php { 
php {     $image->setAttribute('x-data-src', $src);
php {     $image->removeAttribute('src');
php {     $image->parentNode->appendChild($noscript);
php {     //$image->parentNode->appendChild($newImage);
php { 
php { }
limit exceeded
php > $body = $doc->saveHTML();
php > 
php > echo $body;
<!DOCTYPE html>
<html><head><title>Sample</title></head><body>
<img x-data-src="https://example.com/images/example.jpg">
<noscript>
    <img x-data-src="https://example.com/images/example.jpg">
        <noscript>
        <img x-data-src="https://example.com/images/example.jpg">
            <noscript>
            <img x-data-src="https://example.com/images/example.jpg">
                <noscript>
                <img src="https://example.com/images/example.jpg">
                </noscript>
            </noscript>
        </noscript>
    </noscript>
    </body></html>
php > 
如果你把它注释掉,递归就消失了。请注意,当它递归时,x-data-src将应用于除最后一个之外的所有对象

我还没有完全弄清楚是什么导致了这种行为,但希望能够将其可视化将有助于进一步诊断

**更新

OP拿着这个并用它运行,用他的解决方案完成了答案,如下所示



问题在于,
getElementsByTagName
返回一个
LiveNodeList
,因此将图像附加到文档将导致无限递归

我首先在一个简单的数组中收集所有的图像标签来解决这个问题

<?php

$html = '<!DOCTYPE html><html><head><title>Sample</title></head><body><img src="https://example.com/images/example.jpg"></body></html>';

$doc = new DOMDocument();
$doc->loadHTML($html);

$images = $doc->getElementsByTagName('img');

$normal_array = [];
foreach ($images as $image) {
    $normal_array[] = $image;
}


// Now we have all tags in a simple array NOT in a Live Node List

foreach ($normal_array as $image) {

    $src = $image->getAttribute('src');
    $noscript = $doc->createElement('noscript');

    $node = $doc->createElement('img'); //If a uncomment this line the script just times out
    $node->setAttribute('src', $src);

    $noscript->appendChild($node);

    $image->setAttribute('x-data-src', $src);
    $image->removeAttribute('src');
    $image->parentNode->appendChild($noscript);

    //$image->parentNode->appendChild($newImage);

}

$body = $doc->saveHTML();

Afaik div没有
src
属性。
getElementsByTagName
至少根据DOM规范返回一个活动节点列表。如果PHP/DomDocuments实现也是如此,然后,我不确定在这样一个节点列表上循环,同时在其中的元素上移动是否是一个好主意……问题是,它可以与div一起工作,但不能与img@CBroe您是对的,问题在于getElementsByTagName返回一个活动节点列表所有的
php>
?交互模式是什么。您可以使用
php-a
在终端中运行,有人投票反对我花时间来说明发生了什么?我不可能把这些都写进评论里。有时候,答案是通过调整自己的注意力来找到的。
<?php

$html = '<!DOCTYPE html><html><head><title>Sample</title></head><body><img src="https://example.com/images/example.jpg"></body></html>';

$doc = new DOMDocument();
$doc->loadHTML($html);

$images = $doc->getElementsByTagName('img');

$normal_array = [];
foreach ($images as $image) {
    $normal_array[] = $image;
}


// Now we have all tags in a simple array NOT in a Live Node List

foreach ($normal_array as $image) {

    $src = $image->getAttribute('src');
    $noscript = $doc->createElement('noscript');

    $node = $doc->createElement('img'); //If a uncomment this line the script just times out
    $node->setAttribute('src', $src);

    $noscript->appendChild($node);

    $image->setAttribute('x-data-src', $src);
    $image->removeAttribute('src');
    $image->parentNode->appendChild($noscript);

    //$image->parentNode->appendChild($newImage);

}

$body = $doc->saveHTML();