PHP DOMDocument parentNode->replaceChild 导致 foreach 跳过下一项
PHP DOMDocument parentNode->replaceChild causing foreach to skip next item
我正在使用 DOMDocument 解析 html 变量中的 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;
这是有问题的代码行
$iframe->parentNode->replaceChild($link, $iframe);
一个DOMNodeList, such as that returned from getElementsByTagName
, is "live":
that is, changes to the underlying document structure are reflected in all relevant NodeList... objects
因此,当您删除该元素(在本例中是通过将其替换为另一个元素)时,它不再存在于节点列表中,而下一个元素将占据其在索引中的位置。然后当 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++;
}
今天遇到这个问题,根据答案,我给大家做了一个简单的代码解决方案
$iframes = $dom->getElementsByTagName('iframe');
for ($i=0; $i< $iframes->length; $i++) {
$iframe = $iframes->item($i);
if("condition to replace"){
// do some replace thing
$i--;
}
}
希望对您有所帮助。
我正在使用 DOMDocument 解析 html 变量中的 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;
这是有问题的代码行
$iframe->parentNode->replaceChild($link, $iframe);
一个DOMNodeList, such as that returned from getElementsByTagName
, is "live":
that is, changes to the underlying document structure are reflected in all relevant NodeList... objects
因此,当您删除该元素(在本例中是通过将其替换为另一个元素)时,它不再存在于节点列表中,而下一个元素将占据其在索引中的位置。然后当 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++;
}
今天遇到这个问题,根据答案,我给大家做了一个简单的代码解决方案
$iframes = $dom->getElementsByTagName('iframe');
for ($i=0; $i< $iframes->length; $i++) {
$iframe = $iframes->item($i);
if("condition to replace"){
// do some replace thing
$i--;
}
}
希望对您有所帮助。