2012-04-16 18 views
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(); 

上記のコードは、例外が発生しなければならないログインしますが、例外が他の場所で投げをアプリケーションのデフォルトの例外ハンドラによって処理され、ログに記録されないようにする必要があります。これは何とか可能ですか?それの要点は、try/catch文でDBクラスのすべてをラップして、例外を記録できるようにしたくないということです。

例外ハンドラへの特定のタイプの例外のみをリダイレクトし、他のすべてのハンドラがデフォルトのハンドラに移動できるようにすることは可能ですか? set_exception_handler()を使用してすべての例外をリダイレクトするか、またはnoneをカスタム例外ハンドラにリダイレクトすることしかできないようです。

+0

問題の根本原因は、例外ハンドラではなく静的クラス関数を使用していることです。 – hakre

+0

それを詳しく教えてもらえますか? – BadCash

+0

静的クラスは、グローバル例外ハンドラのようなグローバル関数の集合です。バックトレースする必要がある例外式の種類については、例外の型を使ってこれを解決する方がはるかに直接的ですが、例外式のタイプには、非グローバルな具体的な型が必要です。具体的な型は静的なクラスとは異なる概念なので、根本的な原因は単に関数の集合であり、例外が含まれるオブジェクト指向プログラミングとあまり関係がない静的なクラスです。おそらくエラーの場合には 'FALSE'を返すほうがよいでしょう。 – hakre

答えて

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_handlerdocsに関連するコメントがあり、静的メソッドを使用しているようです。このコメントは、 "displque dot comのmarques"によって投稿されました。

+0

私は何を達成したいのか不明確でした。私のDBクラスはPDOデータベースのラッパーです。私はtry/catchをしなくてもそれらのPDOExceptionをキャッチしたいと思います。あなたのソリューションは動作しますが、PDOExceptionを捕まえるためにはtry/catchを使用しなければならず、そこからDBExceptionをスローするか、何らかの形でログ関数を呼び出すのですか? 私が実際に達成したいことをよりよく反映するために、オリジナルの投稿のコードを編集しました。 – BadCash

+0

こんにちは、私の更新を見ましたか?それは動作しましたか? –

関連する問題