2012-04-16 41 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