PHP DOMDocument parentNode-> replaceChild导致foreach跳过下一项

haw*_*126 1 php foreach iframe html-parser

$content使用DOMDocument 解析变量中的html,以将所有iframe替换为图片。foreach仅替换ODD iframe。我已经删除了foreach中的所有代码,并发现引起该问题的代码是:'$ iframe-> parentNode-> replaceChild($ link,$ iframe);'

为什么foreach会跳过所有奇数iframe?

代码:

        $count = 1;
        $dom = new DOMDocument;
        $dom->loadHTML($content);
        $iframes = $dom->getElementsByTagName('iframe');
        foreach ($iframes as $iframe) {

            $src = $iframe->getAttribute('src');
            $width = $iframe->getAttribute('width');
            $height = $iframe->getAttribute('height');

            $link = $dom->createElement('img');
            $link->setAttribute('class', 'iframe-'.self::return_video_type($iframe->getAttribute('src')).' iframe-'.$count.' iframe-ondemand-placeholderImg');
            $link->setAttribute('src', $placeholder_image);
            $link->setAttribute('height', $height);
            $link->setAttribute('width', $width);
            $link->setAttribute('data-iframe-src', $src);

            $iframe->parentNode->replaceChild($link, $iframe);

            echo "here:".$count;
            $count++;
        }

        $content = $dom->saveHTML();

        return $content;
Run Code Online (Sandbox Code Playgroud)

这是代码的问题所在

        $iframe->parentNode->replaceChild($link, $iframe);
Run Code Online (Sandbox Code Playgroud)

use*_*918 5

一个DOMNodeList之后,如从返回的getElementsByTagName,是“活”

也就是说,对基础文档结构的更改反映在所有相关的NodeList ...对象中

因此,当您删除该元素时(在这种情况下,将其替换为另一个元素),该元素将不再存在于节点列表中,并且下一个行将占据其在索引中的位置。然后,当foreach命中下一个迭代,并因此命中下一个索引时,将有效地跳过一个。

不要foreach像这样从DOM中删除元素。


相反,一种有效的方法是使用while循环来迭代和替换,直到您的$iframes节点列表为空。

例:

while ($iframes->length) {
    $iframe = $iframes->item(0);

    $src = $iframe->getAttribute('src');
    $width = $iframe->getAttribute('width');
    $height = $iframe->getAttribute('height');

    $link = $dom->createElement('img');
    $link->setAttribute('class', 'iframe-'.self::return_video_type($iframe->getAttribute('src')).' iframe-'.$count.' iframe-ondemand-placeholderImg');
    $link->setAttribute('src', $placeholder_image);
    $link->setAttribute('height', $height);
    $link->setAttribute('width', $width);
    $link->setAttribute('data-iframe-src', $src);

    $iframe->parentNode->replaceChild($link, $iframe);

    echo "here:".$count;
    $count++;
}
Run Code Online (Sandbox Code Playgroud)


tak*_*412 5

今天面对这个问题,并以答案为指导,我为你们做了一个简单的代码解决方案

$iframes = $dom->getElementsByTagName('iframe');
for ($i=0; $i< $iframes->length; $i++) {
    $iframe = $iframes->item($i);
    if("condition to replace"){
        // do some replace thing
        $i--;
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这有帮助。