我有一个带有异常处理程序的脚本。在异常之后脚本退出之前,此异常处理程序会清除几个连接。
我想从这个异常处理程序中重新抛出异常,以便它由PHP自己的最后一个异常处理程序处理,其中错误被写入PHP的错误日志,或者在PHP中配置的默认值。的.ini。
不幸的是,这似乎不太可能,如下所述:
http://www.php.net/manual/en/function.set-exception-handler.php#68712
将导致致命错误:抛出没有堆栈帧的异常
还有另一种方法可以将错误压缩到堆栈中,以便PHP在我的异常处理程序清理完成后处理它吗?
答案 0 :(得分:15)
你不能从异常处理程序中重新抛出,但是,还有其他地方可以。例如,您可以通过将事物封装到自己的类中来解除对处理程序的重新抛出,然后使用__destruct()
函数(PHP 5.3,Demo):
<?php
class ExceptionHandler
{
private $rethrow;
public function __construct()
{
set_exception_handler(array($this, 'handler'));
}
public function handler($exception)
{
echo "cleaning up.\n";
$this->rethrow = $exception;
}
public function __destruct()
{
if ($this->rethrow) throw $this->rethrow;
}
}
$handler = new ExceptionHandler;
throw new Exception();
将其放入我的错误日志中:
[29-Oct-2011 xx:32:25] PHP Fatal error: Uncaught exception 'Exception' in /.../test-exception.php:23
Stack trace:
#0 {main}
thrown in /.../test-exception.php on line 23
答案 1 :(得分:8)
只需捕获异常并自行记录消息,然后重新抛出。
try {
$foo->doSomethingToCauseException();
} catch (Exception $e) {
error_log($e->getMessage());
throw $e;
}
如果你冒泡到顶部并且PHP无法处理,则会导致未捕获的异常。
答案 2 :(得分:3)
将导致致命错误:抛出没有堆栈帧的异常
此错误意味着您的异常是从不属于脚本的代码中抛出的(据PHP所知)。此类代码的示例包括使用set_exception_handler()设置的自定义异常处理程序以及任何类析构函数方法。除了不从这样的代码中抛出异常,别无选择。
如果您想要PHP本机错误处理,我建议您拨打trigger_error()。如果您没有自定义错误处理程序并且使用了合适的错误类型,它应该记录错误。例如,E_USER_ERROR应该没问题。
答案 3 :(得分:2)
只需将异常重新抛出为RunTimeException,它将保留stacktrace:)
try {
// bad exception throwing code
} catch (Exception $e) {
throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
}
答案 4 :(得分:0)
来自http://www.php.net/manual/en/function.set-exception-handler.php#88082 我读: 另一种解决方案是在异常处理程序的开头恢复错误处理程序。 你试过吗?