[PHP-users 11555] Re: クラス内でのエラー処理

Eiji Miwa php-users@php.gr.jp
Tue, 19 Nov 2002 04:54:26 +0900


 ミワです。和田さんご教授ありがとうございます。

WADA Masashi wrote...
>    > $old_eh = set_error_handler( array( $this, "error_handler" ) );
>
>のように配列は指定できないと思います。どうして配列が指定できると
>思われたのでしょうか?

 array_walk などで、例えばクラス内の関数から同じクラス内の関数を
 指定する場合に、
 array_walk( $str, array( $this, "myfunction" ) );
 という書き方ができるので、関数の指定なのだから同じように
 できるはず と思っていました。

WADA Masashi wrote...
> で、この部分を以下のように変更して試してみたら、一応動きました。
>ミワさんが目指すものとは違うのでしょうが・・・。

 ご指示どうりに修正して、エラー処理の部分を...
 print( $errno );
 ...として
  trigger_error( "Error!", E_USER_ERROR );
 ...でエラーを出してみましたが、「256」とは表示されませんでした。
 Error Handler をうまく設定出来ていないようです。

WADA Masashi wrote...
>ミワさんのスクリプトでは、エラーハンドラが
>
>    function error_handler( $errno, $errmsg, $filename, $linenum, $vars )
>
>と定義されていますが、引数の数が4つになっていません。引数の数が
>異なっていても、なぜか set_error_handler() は正常終了するようで
>すが、trigger_error() 実行時に肝心のエラーハンドラーが呼び出され
>ません。

 http://www.php.net/manual/ja/function.set-error-handler.php

 「ユーザ関数の引数は2つ、エラーコードとエラーを記述する文字列です。
   PHP 4.0.2 からオプションのパラメータが3つ追加されています。」
 
 ...と書かれていますので、4.0.2以降であれば引数は5つのようです。

WADA Masashi wrote...
> しかし上記の回避方法では、エラーハンドラクラスのインスタンスを
>生成しても、実際に実行されるエラーハンドラは 静的メソッドとして呼
>び出されるので、あまり良い解決策ではないでしょう。
> 代案といっても、これといったものが思い浮かばないのですが・・・。
>    class Error_handler {
>        ...
>    }
>    function my_error_handler($errno, $errstr, $errfile, $errline) {
>        $eh = new Error_handler();
>        ...
>    }
>    set_error_handler("my_error_handler");

 こちらはまだ試させてもらっていないのですが、上記URLの中に
 そのものズバリな解決方法が書かれていました。
 #申し訳ありません、見逃していました。
 
 エラー関数のリファレンスをグロ−バル変数に入れて、
 Error Handler にはスルー用の関数を設定。
 スルー用の関数から、グロ−バル変数に入れたエラー関数を呼んでやるようです。
 おもしろいですね。

 以下サンプルです。
 #ob_startなどは適当に追加してください。

----- myclass.inc
<?php
error_reporting( E_ALL );
function my_set_error_handler( $callback_func )
{
 if ( !is_array( $callback_func) )
 { return set_error_handler( $callback_func ); }
 if ( !is_object( $callback_func[0] ) ||
      !method_exists( $callback_func[0], $callback_func[1]) )
 { return false; }
 $GLOBALS["_ERROR_HANDLER_OBJECT"] = &$callback_func[0];
 $GLOBALS["_ERROR_HANDLER_METHOD"] = $callback_func[1];
 
 function error_handler_passthru( $no, $str, $file, $line, $var )
 {
  $GLOBALS["_ERROR_HANDLER_OBJECT"] ->
  $GLOBALS["_ERROR_HANDLER_METHOD"]( $no, $str, $file, $line, $var );
 }
 return set_error_handler( "error_handler_passthru" );
}
class myclass
{
 function error_handler( $errno, $errmsg, $filename, $linenum, $vars )
 {
  echo "<pre>errno: $errno
  errstr: $errstr
  errfile: $errfile
  nerrline: $errline
  errcontext:\n";
  print_r($errcontext);
 }
}
?>
----

---- test.php
<?php
 require_once ("myclass.inc");
 $mc = new myclass();
 $oldhandler = my_set_error_handler( array( &$mc, "error_handler" ) );
?>
----