2017-05-23 1 views
1

phD DomDocumentを使用してイメージ要素をnoscript要素に追加しようとすると、奇妙な問題が発生します。php domdocumentを使用してimg要素を追加できない

新しいdivノードを作成した場合、noscript要素に問題なく追加できますが、イメージ要素を追加しようとするとすぐにスクリプトがタイムアウトします。

私は間違っていますか?

<?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; 
+0

内のすべての画像タグを収集して、それを解決しました。 –

+1

'getElementsByTagName'は少なくともDOM仕様に従って_live_ NodeListを返します。それがPHP/DomDocumentsの実装にも当てはまる場合は、その中の要素を移動しながら、そのようなNodeListをループするのが良いかどうかはわかりません。 – CBroe

+1

これはdivで動作することですが、 img – Cesar

答えて

0

あなたは再帰的ループに巻き込まれています。これは、何が起こっているのかを視覚化するのに役立ちます。私は、わかりやすくするためにインデント追加しました:

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 > 

再帰を引き起こして面倒なラインは、あなたがそれをコメントアウトした場合、再帰がなくなる

$image->parentNode->appendChild($noscript); 

です。 recursesを実行すると、x-data-srcが最後のものを除くすべてに適用されていることに注意してください。

私はこの現象の原因をはっきりとは分かっていませんが、それを視覚化できればさらに診断するのに役立ちます。

** UPDATE

はOPはこれを取り、それを走り、以下に示すように、彼のソリューションとの答えを完了しました。


問題がgetElementsByTagName戻っLiveNodeListがそうドキュメントにイメージを追加すると、無限再帰を引き起こすという事実でした。

私はのdivのは、 `src`属性を持っていない私の知る限り最初の単純な配列

<?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(); 
+0

すべての 'php>'は何ですか? –

+0

対話モード。 'php -a'を使用して端末で実行することができます –

+0

誰かが何が起こっているかを説明する時間をとって下さったのですか?私はすべてのことをコメントに入れることはできなかった。時には、答えは、自分の焦点を再調整することによって見出される。 –

関連する問題