【问题标题】:Set an exception handler for all exceptions thrown inside class?为类内抛出的所有异常设置异常处理程序?
【发布时间】:2012-04-28 05:47:42
【问题描述】:

我知道可以使用 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() 将所有异常或不重定向到自定义异常处理程序?

【问题讨论】:

  • 问题的根本原因是使用静态类函数,而不是异常处理程序。
  • 静态类是全局函数的集合——就像全局异常处理程序一样。要了解异常表达式的类型,您需要回溯,但更直接的是用异常类型来解决这个问题 - 但异常表达式的类型需要非全局的具体类型。具体类型是与静态类不同的概念,因此根本原因是静态类仅仅是函数的集合,它们与异常所属的面向对象编程没有太大关系。您最好返回FALSE,以防万一出现错误。

标签: php class exception-handling


【解决方案1】:

如果我理解您的要求,您应该能够执行以下操作(未经测试):

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();

-- 更新--

根据您的评论,您的代码 sn-p 非常接近。没有函数set_class_exception_handler,试试改成set_exception_handler。不确定您是否已经阅读过这篇文章,但有一条评论与 docs 相关联的 set_exception_handler 使用静态方法并且似乎可以工作。该评论由“marques at displague dot com”发布。

【讨论】:

  • 我似乎有点不清楚我想要完成什么。我的 DB 类是 PDO 数据库的包装器,我想捕获那些 PDOExceptions 而不必到处进行 try/catch。您的解决方案会起作用,但要捕获 PDOException,我仍然必须使用 try/catch 并从那里抛出 DBException 或以某种方式调用我的日志函数......对吗?我在原始帖子中编辑了代码,以更好地反映我真正想要完成的任务。
猜你喜欢
  • 2011-12-12
  • 1970-01-01
  • 2013-07-24
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-10
  • 1970-01-01
相关资源
最近更新 更多