Fatal error: Maximum function nesting level of ‘100′ reached, aborting!


当然なのかもしれませんが。

PHPで再帰的なループ処理を行うとき、そのループカウントが100回を越えるとエラーになるようです。
処理の見直しが妥当なのかもしれませんが、あとちょっとで終わるところだったのでちょっと検索。
変更可能のようです。

【php.ini】

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; for Xdebug
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
extension="xdebug.so
xdebug.max_nesting_level = 256

これでOK。
apacheを再起動して再度処理を実行。

PHP Warning: Xdebug MUST be loaded as a Zend extension in Unknown on line 0.

違うエラーが。。。
まぁ、xdebugがなんなのかちゃんと知らずに設定してもだめだってことですね。

名前のとーり、デバッグを支援してくれるモジュールのことで、PECLのパッケージでも提供されているようです。
で、インストールされているのか確認してみると、

[[2010-07-20 21:35:31]–[paz@paz-para]]
[[11 Dirs]-[5 Files]]–((8825)(23)(1))
[[ ~/public_html ]]-> php -i | grep xdebug
PHP Warning: Xdebug MUST be loaded as a Zend extension in Unknown on line 0
PHP Warning: Module ‘xdebug’ already loaded in Unknown on line 0
/etc/php.d/xdebug.ini,
xdebug
xdebug support => enabled



xdebug.max_nesting_level => 256 => 256

入ってるっぽいですし、さっきの設定変更(ループの上限の変更)も反映されているっぽい。

でも、さっき見たエラーも出てる。

もーちょい調べてみると、php-develが必要とか必要じゃないとか。
確認してみると、

[[2010-07-20 21:41:55]–[paz@paz-para]]
[[11 Dirs]-[5 Files]]–((8831)(29)(1))
[[ ~/public_html ]]-> sudo yum list installed | grep php
php.i386 5.2.9-2.fc10 @updates
php-cli.i386 5.2.9-2.fc10 @updates
php-common.i386 5.2.9-2.fc10 @updates
php-gd.i386 5.2.9-2.fc10 @updates
php-mbstring.i386 5.2.9-2.fc10 @updates
php-mysql.i386 5.2.9-2.fc10 @updates
php-pdo.i386 5.2.9-2.fc10 @updates
php-pear.noarch 1:1.7.2-2.fc10 @fedora
php-pecl-xdebug.i386 2.0.5-1.fc10 @updates
php-xml.i386 5.2.9-2.fc10 @updates

入ってない。
ので入れてみる。

[[2010-07-20 21:42:11]–[paz@paz-para]]
[[11 Dirs]-[5 Files]]–((8832)(30)(1))
[[ ~/public_html ]]-> sudo yum install php-devel
読み込んだプラグイン:fastestmirror, refresh-packagekit
Loading mirror speeds from cached hostfile
* fedora: ftp.tsukuba.wide.ad.jp
* updates: ftp.tsukuba.wide.ad.jp
インストール処理の設定をしています
依存性の解決をしています
–> トランザクションの確認を実行しています
—> パッケージ php-devel.i386 0:5.2.9-2.fc10 を更新に設定しました
–> 依存性の処理をしています: automake のパッケージ: php-devel-5.2.9-2.fc10.i386
–> 依存性の処理をしています: autoconf のパッケージ: php-devel-5.2.9-2.fc10.i386
–> トランザクションの確認を実行しています
—> パッケージ autoconf.noarch 0:2.63-1.fc10 を更新に設定しました
—> パッケージ automake.noarch 0:1.11-2.fc10 を更新に設定しました
–> 依存性解決を終了しました
 
依存性を解決しました
 
========================================================================================================================================
Package Arch Version Repository Size
========================================================================================================================================
インストールしています:
php-devel i386 5.2.9-2.fc10 updates 552 k
依存性関連でのインストールをします:
autoconf noarch 2.63-1.fc10 fedora 937 k
automake noarch 1.11-2.fc10 updates 574 k
 
Transaction Summary
========================================================================================================================================
Install 3 Package(s)
Upgrade 0 Package(s)
 
総ダウンロード容量: 2.0 M
これでいいですか? [y/N]y
パッケージをダウンロードしています:
(1/3): autoconf-2.63-1.fc10.noarch.rpm | 937 kB 00:00
(2/3): automake-1.11-2.fc10.noarch.rpm | 574 kB 00:00
(3/3): php-devel-5.2.9-2.fc10.i386.rpm | 552 kB 00:00
—————————————————————————————————————————————-
合計 2.3 MB/s | 2.0 MB 00:00
rpm_check_debug を実行しています
トランザクションのテストを実行しています
トランザクションのテストを終了しました
トランザクションのテストを成功しました
トランザクションを実行しています
インストールし : autoconf-2.63-1.fc10.noarch 1/3
インストールし : automake-1.11-2.fc10.noarch 2/3
インストールし : php-devel-5.2.9-2.fc10.i386 3/3
 
インストールしました:
php-devel.i386 0:5.2.9-2.fc10
 
依存性関連をインストールしました:
autoconf.noarch 0:2.63-1.fc10 automake.noarch 0:1.11-2.fc10
 
完了しました!

再起動して、もう一回確認してみるもダメ。
やっぱインストールされてないのかなーと、pecl install xdebugを実行してみると、

[[2010-07-20 21:46:37]–[paz@paz-para]]
[[11 Dirs]-[5 Files]]–((8838)(36)(1))
[[ ~/public_html ]]-> sudo pecl install xdebug



Build process completed successfully
Installing ‘/usr/lib/php/modules/xdebug.so’
install ok: channel://pecl.php.net/xdebug-2.1.0
configuration option “php_ini” is not set to php.ini location
You should add “extension=xdebug.so” to php.ini

入ってなかったのかなー。

参考サイトで拝見した、xdebug.iniの設定もしておく。
どうやらphp.iniには直接追記せずに、こっちに書いたほうがいいらしい。
なのでさきほど追加したphp.iniの設定は消しましょう。

【/etc/php.d/xdebug.ini】

; Enable xdebug extension module
; extension=xdebug.so
xdebug.collect_params = On
xdebug.dump.GET = *
xdebug.dump.POST = *
zend_extension=/usr/lib/php/modules/xdebug.so
xdebug.max_nesting_level = 256

xdebugは普通の拡張モジュールとは違い、Zendのモジュールだから絶対パスで書かないといけないとかなんとか。
パスはlocateコマンド、もしくはpear config-showコマンドの「ext_dir」項目で確認できます。

さらに、コマンドラインからPHPのモジュールを確認するときは「php -i」じゃなく、「php -m」でした。

[PHP Modules]
bz2
calendar
ctype



[Zend Modules]
Xdebug

大丈夫そうです。

この状態で再帰処理を実行してみたところ、無事に処理が完了されました。

とりあえず、やったこと・わかったことをまとめると、

  • 再帰処理が深すぎてエラーがでた
  • エラーを回避するためにXdebugの設定を変更
  • xdebugがインストールされていなくてエラー
  • xdebugをpeclコマンドを利用してインストール
    ※このとき、php-develをインストールする必要がある
  • xdebugの設定は/etc/php.d/xdebug.iniに記述
    ※xdebugはZendの拡張モジュールなので絶対パスで記述しないといけない
  • phpのモジュールをコマンドラインから確認する時は「php -m」

こーゆーことですね。
php-develのインストールとかも結局は必要だったようなので結果オーライです。
勉強になりました。

で、xdebugってどうやら便利なモジュールみたいです。
これも今度調べないと。

■参考サイト

PHPで再帰処理を100ループ以上に増やす: PHPの種 ブログ
http://www.php-seed.net/blog/archives/374

PECLとか使えるようにする(+ xdebugインストール方法)::VMWare×CentOS5 Windowsでカンタン開発環境 – 肉とご飯と甘いもの @ sotarok
http://d.hatena.ne.jp/sotarok/20071225/vmware_centos5_101#

モダンなPHPの開発環境の構築方法 – 肉とご飯と甘いもの @ sotarok
http://d.hatena.ne.jp/sotarok/20100717/modern_phpenv

CentOS 5.3 x86_64 にPHP開発環境を用意したメモ – はかつまぶろぐ
http://blog.be55.com/2009/05/centos-53-x86-64-php.html

,

  1. #1 by reveremind at 7月 22nd, 2010

    いやー知りませんでした。
    PHPで再帰をつかってコードを書くことは度々あるのですが、
    まさか100回以上ネストするとアボートされるとは。
    やはり、スタックを不必要に消費するので、あまり末尾再帰最適化が実装されていない言語で計算量の多い再帰は考えものですね。
    勉強になりました。

  2. #2 by paz at 7月 23rd, 2010

    >>reveremindさん
    よく考えずに再帰に手を出してみたらこのざまでしたw

    末尾再帰最適化ですか・・・
    んー、ちょっと勉強しときます。

    今度、再帰とはなんたるかを伝授してください!

(will not be published)
  1. No trackbacks yet.