PHP中的异常 - set_exception_handler输出

时间:2015-04-01 13:10:23

标签: php error-handling

我现在开始使用set_exception_handler。 我测试的第一个地方是我的PDO图层的 try / catch 块。

我强制使用不正确的数据库凭据进行异常处理。 (这是在我应用

之前
<?php  

function log_exception($exception){
    print_r($exception);    
}

set_exception_handler("log_exception");

try { 
    $dbh = new PDO();
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    echo "connected!! \n";
} catch (PDOException $e) { 
    print_r($e); // let's see what it looks like
    throw new Exception($e); 
}
?>

您会在 catch 以及 log_exception 函数中看到print_r

这是从 print_r($ e)

显示的内容
PDOException Object
(
    [message:protected] => SQLSTATE[28000] [1045] Access denied for user 'localhost'@'127.0.0.1' (using password: YES)
    [string:Exception:private] =>
    [code:protected] => 1045
    [file:protected] => /var/www/html/test.php
    [line:protected] => 35
    [trace:Exception:private] => Array
        (
            [0] => Array
                (
                    [file] => /var/www/html/test.php
                    [line] => 35
                    [function] => __construct
                    [class] => PDO
                    [type] => ->
                    [args] => Array
                        (
                            [0] => mysql:host=127.0.0.1;dbname=db_tests;charset=utf8
                            [1] => test
                            [2] => test
                        )

                )

        )

    [previous:Exception:private] =>
    [errorInfo] =>
)

这是 log_error()函数中 print_r($ exception)显示的内容:

Exception Object
(
    [message:protected] => exception 'PDOException' with message 'SQLSTATE[28000] [1045] Access denied for user 'localhost'@'127.0.0.1' (using password: YES)' in /var/www/html/test.php:34
Stack trace:
#0 /var/www/html/test.php(34): PDO->__construct('mysql:host=127.0...', 'test', 'test')
#1 {main}
    [string:Exception:private] =>
    [code:protected] => 0
    [file:protected] => /var/www/html/test.php
    [line:protected] => 34
    [trace:Exception:private] => Array
        (
        )

    [previous:Exception:private] =>
)

它们有什么不同? 我假设任何异常对象传递到 log_error()函数将与 catch 中生成的函数相同。

我错过了什么吗?

...

2 个答案:

答案 0 :(得分:3)

如果你想转发它,你应该抛出同样的例外,而不是新的:

throw $e;

答案 1 :(得分:2)

这是因为它们是两种不同的例外。

正如您在此处所看到的,PDOException有一些Exception没有的属性。 你在catch中做的是抛出一个新的Exception,将前一个Exception作为消息。 Exception构造函数需要将字符串作为消息传递,然后获取PDOExceptions方法__toString的输出。 其他属性将根据最后Exception被抛出的位置进行设置。

正如Cristik所说,如果你想通过Exception,你可以使用throw $e。这会将此Exception传递给异常处理程序。

创建新的Exception时,将根据实例化Exception的位置设置行和文件属性。跟踪也会有所不同。但如果你扔掉你抓到的那个,那么所有这些都将保持不变。