1

set_exception_handler() を使用して独自のグローバル例外ハンドラを設定できることは知っています。しかし、クラス内に例外ハンドラーを設定して、クラス自体内でスローされた例外のみをキャッチすることは可能ですか? 違いがあれば、静的クラスを使用しています。

私はこのようなことをしたいです (つまり、「set_class_exception_handler()」関数を探しています):

class DB{

    $dbh = NULL;

    public static function connect( $host, $database, $username, $password, $db_type = 'mysql' ){
        static::$dbh = new PDO( $db_type.':host='.$host.';dbname='.$database, $username, $password );
    }

    public static function init(){
        set_class_exception_handler( array("DB", "e_handler") );
    }

    public static function e_handler($e){
        /* Log exception */
    }

    public static function test(){
        $stmt = $dbh->prepare("SELET username FROM users WHERE id=:id");
        // SELECT is misspelled and will result in a PDOException being thrown
    }

}

DB::init();
DB::connect( 'localhost', 'database', 'username', 'password' );
DB::test();

上記のコードにより、例外がログに記録されるはずですが、アプリケーションの他の場所でスローされた例外は、デフォルトの例外ハンドラーによって処理され、ログに記録されません。これはどういうわけか可能ですか?肝心なのは、例外をログに記録できるようにするために、DB クラスで実行するすべてを try/catch ステートメントでラップする必要がないということです。

または、特定の種類の例外のみを例外ハンドラーにリダイレクトし、他のすべての例外を既定のハンドラーにリダイレクトすることは可能ですか? set_exception_handler() を使用して、すべての例外をカスタム例外ハンドラーにリダイレクトするか、何もリダイレクトしないかのどちらかしかできないようです。

4

1 に答える 1

0

あなたが求めていることを理解できれば、次のことができるはずです(テストされていません):

class DBException extends Exception
{
    public function __construct($message = null, $code = 0, Exception $previous = null)
    {
        parent::__construct($message, $code, $previous);

        error_log($message);
    }
}

class DB
{
    public static function test() {

        // We overrode the constructor of the DBException class
        // which will automatically log any DBexceptions, but will not autolog 
        // any other exceptions
        throw new DBException('Something bad happened.');
    }
}

// Calling code

// This will throw fatal due to uncaught exception
// Because we are not handling the thrown exception
DB::test();

- アップデート -

あなたのコメントによると、あなたのコード スニペットは非常に近いものです。機能がありません。set_class_exception_handlerに変更してみてくださいset_exception_handler。これを既に読んだかどうかはわかりませんが、静的メソッドを使用し、機能しているように見えるドキュメントに関連するコメントがあります。set_exception_handlerこのコメントは、「marques at displague dot com」によって投稿されました。

于 2012-04-16T21:37:37.683 に答える