Simple HTML DOM Parserで再帰処理100回エラー

2011/05/10

まずは結論。

body内のplaintextを取得する場合は、空タグを削除してパースする。

何が起きたのかっていうと色んなサイトをパースしてたら下記のようなエラーが発生した。

Fatal error: Maximum function nesting level of ‘100’ reached, aborting! in ~

調べると再帰処理を100回以上するとでてくるらしい。
そもそも再帰処理なんてやってないっていうより…「再帰処理って何?」って感じなんだよね。

再帰処理について

「自分で自分自身を実行する」とか意味不明な説明が多い。
サンプルソースを探しても長くて解読が面倒。
たまたま見つけたサンプルソース(URL控えるのを忘れた…)のおかげで何となく理解できた。
理解できたけど普通にループじゃダメなのかな?
使いドコは不明だけど今回は気にしない。

  1. function recursion($a){
  2.   if ($a < 50) {
  3.     echo "{$a}\n";
  4.     recursion($a + 1);
  5.   }
  6. }
  7.  
  8. recursion(1);

Simple HTML DOM Parserの再帰処理

「$dom->plaintext」とかやるとSimple HTML DOM Parserの中で「__get()」とかが実行されていてそこで再帰処理が使われているっぽい。

エラーの考えられる原因の切り分け

「(自作の)スクリプト」から「対象のHTMLファイル」を「Simple HTML DOM Parser」にいれて「$dom->plaintext」をやってウニョウニョしているので「(自作の)スクリプト」と「Simple HTML DOM Parser」と「対象のHTMLファイル」のどれかが原因。

Fatal error: Maximum function nesting level of ‘100’ reached, aborting! in ~

原因の可能性1:(自作の)スクリプト

このエラーの原因と考えられる可能性の高いのは「(自作の)スクリプト」。
アレコレ削っていったんだけど…原因不明。(かなりシンプルなスクリプトに変更してもダメ)

原因の可能性2:対象のHTMLファイル

次に考えられる可能性の高いのは「対象のHTMLファイル」。

ココでは、ファイル容量・文字数・タグ数・変なタグをチェック。
ファイル容量・文字数・タグ数は今まで調べてきたHTMLファイルに比べるとそれほど多くは無いように見える。

変なタグないかなぁと調べると「<wbr>」ってのを大量に発見。
特別興味ないタグなので削除したらエラーが出なくなった。

対処

「$dom->plaintext」をやる前に「<wbr>」をまとめて削除しておく。

「<wbr>の個数」と「タグの数」が100個、もしくは、タグを100種類使うとアウトっぽいような気がするけど…わかんないや。

新たなる問題

「<wbr>」を削除してパースしてたのに再度、再帰処理のエラー。

Fatal error: Maximum function nesting level of ‘100’ reached, aborting! in ~

今度は「<area>」がいっぱい。いっぱいといっても80個弱程度。

対処2

考えるのが面倒なので空タグを削除することにした。
ほしいのはプレインテキストなので空タグは興味無いんだよね。

$str = “「~HTMLソース~」”;
$str = str_ireplace(array('<wbr>', '<br>', '<br />'), "", $str);
$str = preg_replace('/(<img )(\w+)([^<>]*>)/iu', '', $str);
$str = preg_replace('/(<area )(\w+)([^<>]*>)/iu', '', $str);
$dom = str_get_html($str);

上記のような感じにしてみた。

空タグについて

内容が存在しないタグではなく、閉じタグの存在しないタグのこと。
※表現が適しているが不明なので下記に例を示してみる。
※「からタグ」なのか「そらタグ」なのかは知らない。多分「からタグ」だと思う。

■内容が存在するタグ
<h1>reCatnap</h1>や<p>reCatnap</p>など。

■内容が存在しないタグ
<h1></h1>や<p></p>など。

■空タグ(閉じタグが存在しない・不要?)
<img src="">や<area href="">、<br>など。

新着(ニュース関連以外)

2018-07-26
年賀状で「新春」とか書くけど・・・何故なんだろうと8月を目前にした今、疑問に思った。
2018-05-16
PHPで画像のヘッダ情報(?)の「Orientation」を元に画像回転させたい。
2018-03-05
Android Studioをインストール。エミュレータを軽くするトコまで終わらせたかったけど、挫折した。
2018-02-23
プッシュ通知について調べてた時にでてきたServiceWorker。そのServiceWorkerについてのメモ。
2017-12-13
jqueryで取得したDOM要素をオブジェクトじゃなくて、配列で受け取りたい