这种处理PHP错误的方法是否存在“陷阱”?

时间:2010-11-28 12:50:36

标签: php exception exception-handling error-handling

我是PHP的相对新手,但在我看来,PHP的错误处理有点像一个贫民窟,错误和警告穿插异常(并且不让我开始die()) 。因此,我不确定如何最好地创建,解释和处理我的应用程序中的所有错误情况。

我的总体攻击计划大致如下:

  1. 将所有警告/错误转换为例外,使用set_error_handler()将错误包装起来。
  2. 防守代码,抢先检查我预计会出错的事情。仅在我无法直接处理错误时才抛出异常。通常try/catch块将在需要时到位,以处理我自己不会抛出的异常。
  3. 将我的整个应用程序(即我的index.php入口点文件)包装在其自己的try/catch中。如果失败了,我会抛出一个HTTP 500并显示一个合适的错误页面。据推测,这个页面将是一个预编译的文件而不是标题/正文/页脚包含的集合 - 这在很大程度上是因为我仍然可以覆盖像乱码模板文件这样的奇怪异常。我认为这就是为什么谷歌的500级错误页面看起来与他们推出的其他内容有很大不同。
  4. 作为#2和#3的必然结果,因为我希望能够提前处理所有事情,如果我决定抛出我自己的异常,我也期待来捕获错误,而是让它一直冒泡到我的顶级处理程序。这里的想法是,如果我发现它无法处理它,我可能没有能力在其他任何地方处理它。我正在考虑给这些错误他们自己的子类 - 也许CriticalErrorException - 可以直接在我的日志中识别/生成一封电子邮件,以便我可以快速查看。一般来说,我希望这些是可能在开发中发生的事情,但应该通过生产来解决。
  5. 任何使其成为顶部的错误都会记录在数据库中,并将故障转移到日志文件中。如上所述,严重错误会触发电子邮件。如果报告故障转移到文件 - 即存在数据库错误 - 那么也会触发电子邮件。
  6. 我认为这很好地涵盖了大多数情况,但正如我所说,我对PHP非常新,所以我不知道是否存在我忽视的极端情况或奇怪的行为。

    我的计划有哪些缺陷?我怎么克服它们?

1 个答案:

答案 0 :(得分:1)

总的来说,让意外异常冒泡到最高catch区块然后提供HTTP 500的策略很好(许多框架就是这样做的)。

我不同意制作CriticalErrorException - 也许您现在不希望收到某些内容,但您可能会在将来扩展错误处理(可能面对其他应用程序要求) 。扔掉任何自然的东西。在大多数情况下,简单Exception就可以了。

关于PHP错误:您不需要将E_ERROR转换为异常(它会终止您的应用程序,并且也会显示在错误日志中)。尽管如此,你可以很好地处理E_NOTICE,因为通知几乎总是意味着代码中存在不正确的东西。

最后,当谈到引发警告的PHP函数时,我会这样做:

// Assume that php_function() raises E_WARNING and returns FALSE on error
// WARNING: if you have defined a custom error handler, IT WILL STILL BE CALLED
//          even though the @ operator suppresses the error
$result = @php_function($argument); // suppress error
if (!$result) {
    // error handling here
}

而不是:

try {
    $result = php_function($argument);
}
catch (Exception $ex) {
    // error handling here
}

当您打算立即对错误作出反应时,转换为异常的原因并不能真正为您带来任何好处。相反,如果需要有关其错误处理策略的更多信息,第一个代码片段将“告诉”阅读它的开发人员查找php_function的文档。第二个代码段将要求开发人员具体了解应用程序中实现的错误处理知识。

<强>更新

我并不是说你应该使用@来忽略函数调用产生的错误。我所说的是,当使用以这种方式运行的传统PHP函数时,以及当您完全准备好处理错误并从中恢复时,当然它应该不再被视为关于应用程序执行的“错误”。 在这个特定情况中,我建议将其抑制,以便它也不会被报告。