我是PHP的相对新手,但在我看来,PHP的错误处理有点像一个贫民窟,错误和警告穿插异常(并且不让我开始die()
) 。因此,我不确定如何最好地创建,解释和处理我的应用程序中的所有错误情况。
我的总体攻击计划大致如下:
set_error_handler()
将错误包装起来。try/catch
块将在需要时到位,以处理我自己不会抛出的异常。index.php
入口点文件)包装在其自己的try/catch
中。如果失败了,我会抛出一个HTTP 500
并显示一个合适的错误页面。据推测,这个页面将是一个预编译的文件而不是标题/正文/页脚包含的集合 - 这在很大程度上是因为我仍然可以覆盖像乱码模板文件这样的奇怪异常。我认为这就是为什么谷歌的500级错误页面看起来与他们推出的其他内容有很大不同。CriticalErrorException
- 可以直接在我的日志中识别/生成一封电子邮件,以便我可以快速查看。一般来说,我希望这些是可能在开发中发生的事情,但应该通过生产来解决。我认为这很好地涵盖了大多数情况,但正如我所说,我对PHP非常新,所以我不知道是否存在我忽视的极端情况或奇怪的行为。
我的计划有哪些缺陷?我怎么克服它们?
答案 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函数时,以及当您完全准备好处理错误并从中恢复时,当然它应该不再被视为关于应用程序执行的“错误”。 在这个特定情况中,我建议将其抑制,以便它也不会被报告。