この記事は、以前のブログに投稿したものを微修正して再掲載したものです。初出は2011年4月です。
PHPでset_error_handler()って関数を使うと、WARNINGとか NOTICEなどが発生した時に例外を投げてくれるようになります。
参考にしたのはPHPマニュアルのユーザーコメント。
http://tr2.php.net/manual/ja/class.errorexception.php とかね。
処理ごとに WARNINGなどを監視するのはめんどくさいので、これ使って例外投げてもらって まとめて処理できるようになると楽だなと思っていたんだけど、逆に毎回例外が発生して使い勝手が悪くなってしまった。
っていうか、一番取りたいERRORは有無を言わさずプログラム停止するって仕様はどうなのよ?
なんのための例外処理なんだろう?
ERRORはしょうがないから諦めるとして、それ以外は ページ表示した後 WARNING何件 NOTICE何件、詳細はこうって感じで出せるようにならないかなぁ?
と思ったところで、このハンドラ内部で throw するんじゃなくて、例外オブジェクトをコレクトするだけの処理にすればいいんじゃないかなと思ったので、実装してみました。
/** * Error Handlerの定義 * Warningや Noticeなど、発生したメッセージをエラーハンドリングし、 * ErrorExceptionオブジェクトにしておいて、stdClassオブジェクトのプロパティに保存していきます。 * これを Zend_Registryで保持しておくので、後でどこからでも取り出すことができます。 */ { // (E_ALL | E_STRICT)発生時に呼び出される関数を登録します。 set_error_handler( function ($errno, $errstr, $errfile, $errline, $errcontext) { // レジストリに登録があるかを確認し、あれば取り出します。 if (Zend_Registry::isRegistered('myErrorException')) { $myerr = Zend_Registry::get('myErrorException'); } // なければ stdClassオブジェクトを生成し、 // エラーを保存するプロパティを用意して、 // レジストリに登録します。 else { $myerr = new stdClass; $myerr->e = array(); Zend_Registry::set('myErrorException', $myerr); } // ErrorExceptionオブジェクトを生成し、プロパティに格納します。 $myerr->e[] = new ErrorException($errstr, 0, $errno, $errfile, $errline); } , (E_ALL | E_STRICT) ); }
すべての処理が終わった後、これを煮るなり焼くなりすればいいかと^^
Zend_Logで、Firebugのコンソールへ送る方法があるようなので、それを使う実装ができるとなおいいんじゃないかなぁって思います。
あ、これ、PHP5.3以降対応です。無名関数のところを書き変えれば PHP5.2以下でも動作すると思います。
関連する関数・ライブラリについては、以下を参照のこと。
- PHPマニュアル set_error_handler()
http://jp.php.net/manual/ja/function.set-error-handler.php - ZendFrameworkマニュアル Zend_Registry
http://framework.zend.com/manual/ja/zend.registry.html
(しかし、未定義の関数を呼び出した時のFatalErrorは、処理停止じゃなくて例外投げるようにしてほしいな…)