2012-04-16 88 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()重定向所有的異常或者不使用自定義的異常處理程序?

+0

問題的根本原因是使用靜態類函數,而不是異常處理程序。 – hakre 2012-04-16 21:24:25

+0

有意詳細說明一下嗎? – BadCash 2012-04-16 22:50:38

+0

靜態類是全局函數的集合 - 就像全局異常處理程序一樣。要了解異常表達的類型,您需要回溯,但更直接的方法是使用異常類型來解決此問題 - 但異常表達式的類型需要非全局的具體類型。具體類型與靜態類的概念不同,所以根本原因是靜態類,它們僅僅是一個函數集合,並且與面向對象的編程(它們的例外是其中的一部分)無關。你最好在錯誤的情況下返回'FALSE'。 – hakre 2012-04-17 00:07:50

回答

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。不知道你是否已經閱讀過這篇文章,但是docsset_exception_handler有一個評論,它使用靜態方法並且似乎有效。評論發佈於「位於displague dot com的marques」。

+0

看來我對自己想完成的事情有點不清楚。我的數據庫類是一個PDO數據庫的包裝,我想捕獲這些PDOException,而不必嘗試/抓住所有的地方。你的解決方案將工作,但要抓住PDOException我仍然必須使用try/catch並從那裏拋出一個DBException或調用我的日誌功能......不是嗎? 我編輯了原始文章中的代碼,以更好地反映我實際上想要完成的內容。 – BadCash 2012-04-16 23:19:50

+0

嗨,你看到我的更新嗎?它有用嗎? – 2012-04-17 22:45:48