【问题标题】:PHP exceptions thrown in error handler not caught by exception handler错误处理程序中抛出的 PHP 异常未被异常处理程序捕获
【发布时间】:2013-10-01 23:00:25
【问题描述】:

我选择了这个标题,因为我遇到了与此处所述完全相同的问题: PHP exceptions thrown in error handler are not caught by exception handler

作者接受了说他显然做错了什么的答案。 我的错误和异常处理程序在过去两年中运行良好,但现在我面临着完全相同的问题。 我做了代码更新和服务器更新(Plesk 11.5 运行,PHP 版本应该是相同的,是 5.3.2)。我检查了我的代码是否有错误,但测试表明这不是问题所在:

我写了以下测试文件:

function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) {
   throw new Exception("this was an error");
}

function exceptionHandler($e) {
   echo 'exceptionHandler';
}

set_error_handler('errorHandler');
set_exception_handler('exceptionHandler');

// test one:
throw new Exception(); // outputs "exceptionHandler"

// test two - uncomment the first test of course! 
$test->blabla();

第二个测试也应该输出“exceptionHandler”,但它没有! 输出为“致命错误:在第 0 行......./exeptiontest.php 中的非对象上调用成员函数 blabla()”

这个问题现在让我发疯了。这里有什么建议吗?任何导致此问题的 PHP 设置?

【问题讨论】:

  • 你不能用set_error_handler()处理致命错误
  • @SamDufel 是的,我愿意。问题是错误处理程序中抛出的异常没有被异常处理程序捕获..

标签: php exception exception-handling plesk


【解决方案1】:

更新(阅读您的评论后)。

在执行错误处理程序后,程序流程将返回到发生错误之后的表达式。但是将程序流回传给一个致命失败的脚本是不可靠的。这就是错误处理程序不会被致命错误调用的原因。文档说:

以下错误类型无法使用用户定义的函数处理:E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING 以及调用 set_error_handler() 的文件中引发的大部分 E_STRICT。

作为一种解决方法(取决于您的需要),您可以使用register_shutdown_function() 定义关闭函数。


原答案(原来不是这里的问题)

你需要仔细阅读set_exception_handler()documentation,尤其是代码示例:

function exception_handler($exception) {
  echo "Uncaught exception: " , $exception->getMessage(), "\n";
}

set_exception_handler('exception_handler');

throw new Exception('Uncaught Exception');
echo "Not Executed\n";

这意味着$test->blabla() 永远不会被执行。

您可能期望异常处理函数像 catch 块一样工作,但事实并非如此。没错,如果发生异常并且未定义 catch 块,则程序流将接管异常处理程序,该处理程序可能会优雅地关闭脚本 - 但不会更多。如果您想以正确的方式处理异常,请使用try / catch


只是为了更清楚一点:异常处理程序的行为与错误处理程序不同。从异常处理程序返回后,程序将终止,而程序流程从错误处理程序返回时返回到错误后的表达式。

【讨论】:

  • 你错过了我的评论“//测试二 - 当然取消注释第一个测试!”?我知道如果没有它未注释,它将永远不会被执行。问题是不同的
  • 那么答案很简单。 PHP 无法捕获致命错误,并且将程序流传递回致命失败的脚本是不可靠的。你可以定义一个关闭函数
  • 顺便说一句,您可以在此处发布之前从示例中删除第一个测试.. ;)
  • 测试显示正在调用 exceptionHandler。致命错误可以被 set_error_handler() 捕获。你从哪里得到你的信息?
  • 好吧对不起,我不想回到程序流程(你通常会理解“捕获错误”,我只想让我的异常在错误处理程序中执行并且有效在我的 XAMPP 安装上很好,过去两年在服务器上也很好。
猜你喜欢
  • 2011-08-17
  • 1970-01-01
  • 2011-09-16
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-02
相关资源
最近更新 更多