在PHP5中,我应该使用Exception还是trigger_error / set_error_handler?

时间:2020-03-05 18:52:44  来源:igfitidea点击:

两种方式的利弊是什么?有没有正确的方法?

解决方案

回答

这取决于实际情况。当我编写业务逻辑/应用程序内部时,我倾向于使用Exceptions,而对于Validator和类似的东西,则使用trigger_error。

在逻辑级别使用Exceptions的优点是,允许应用程序在发生此类错误的情况下执行此操作。我们允许应用程序选择而不是让业务逻辑知道如何显示错误。

比如说,使用Validate的trigger_error的专业人士以及诸如此类的事情,

回答

我喜欢使用异常的想法,但是我经常会涉及第三方库,然后,如果他们不使用异常,我们最终会使用3-4种解决问题的方法! Zend使用异常。 CakePHP使用自定义错误处理程序,大多数PEAR库使用PEAR :: Error对象。

我在这方面有一个正确的方法。在这种情况下,自定义错误处理程序路由可能是最灵活的。但是,如果仅使用自己的代码或者使用使用它们的库,则异常是一个好主意。

不幸的是,在PHP世界中,我们仍然遭受拒绝死于PHP4的苦难,因此异常(虽然它们可能代表了最佳实践)之类的东西难以置信地变慢了,而每个人仍在编写能够同时在这两种系统中工作的东西4和5.希望这场崩溃现在结束了,尽管到那时,我们将处于6到5之间的紧张关系……

/我握着头...

回答

异常的想法很优雅,并且使错误处理过程非常顺畅。但这仅在我们具有适当的异常类并且在团队开发中适用时,更重要的是"标准"异常。因此,如果我们打算使用异常,则最好先对异常类型进行标准化,或者更好的选择是使用一些流行框架中的异常。适用于PHP的另一件事(我们可以在其中编写结合结构代码的代码对象定向器)是,如果要使用类编写整个应用程序。如果我们正在编写面向对象的代码,那么肯定可以更好地使用异常。毕竟,我认为错误处理流程比trigger_error和其他东西要平滑得多。

回答

显然,没有"正确的方法",但是对此有很多意见。 ;)

就个人而言,我将trigger_error用于异常无法完成的事情,即通知和警告(即我们要记录的内容,但不能以与错误/异常相同的方式停止应用程序的流动(即使我们在某种程度上捕获它们) ))。

我还通常将异常用于假定是不可恢复的条件(发生异常的方法的调用方),即严重错误。如果可以通过非卷积方式实现,则我不使用异常来替代返回具有相同含义的值。例如,如果创建一个查找方法,则通常会在没有找到要查找的内容时返回空值,而不是抛出EntityNotFoundException(或者等效项)。

所以我的经验法则是这样的:

  • 只要找不到某件事是合理的结果,我发现返回和检查空值(或者其他默认值)要比使用try-catch-clause处理它容易得多。
  • 另一方面,如果没有发现严重错误而不是可以从调用者恢复的错误,那么我仍然会引发异常。

在后一种情况下引发异常的原因(与触发错误相反)是,假设我们使用正确命名的Exception子类,则异常的表达性更高。我发现在决定使用哪种异常时,使用PHP标准库的异常是一个很好的起点:http://www.php.net/~helly/php/ext/spl/classException.html

但是,我们可能需要扩展它们以获取针对特定情况的语义上更正确的异常。

回答

异常是发出错误状态/异常情况的一种现代且可靠的方式。使用它们 :)

回答

我们应该在"特殊情况"下使用异常,也就是说,当我们调用方法doFoo()时,我们应该期望它执行,如果由于某种原因doFoo无法执行其工作,则应引发异常。

许多旧的php代码都会采用在发生故障时返回false或者null的方法,但这使事情难以调试,异常使此调试更加容易。

例如,假设我们有一个名为getDogFood()的方法,该方法返回一个DogFood对象数组,如果我们调用此方法,并且在出现问题时返回null,那么由于错误,调用代码将如何判断是否返回了null还是没有狗粮?

关于使用php的内置错误日志记录的遗留代码库,我们可以使用set_error_handler()函数覆盖错误日志记录,然后可以使用该函数来抛出通用Exception。

现在,我们已经拥有所有抛出详细异常的代码,我们可以自由决定如何处理它们,在代码的某些部分中,我们可能希望捕获它们并尝试其他方法,或者可以使用自己的日志记录功能来记录它们可能会记录到数据库,文件或者电子邮件中的任何一个。简而言之,例外情况更为灵活。

回答

如果要在整个应用程序中使用异常而不是错误,则可以使用ErrorException和自定义错误处理程序来实现(有关示例错误处理程序,请参见ErrorException页面)。这种方法的唯一缺点是非致命错误仍然会引发异常,除非捕获异常,否则异常总是致命的。基本上,如果error_reporting设置没有抑制它们,那么即使是E_NOTICE也会停止整个应用程序。

我认为使用ErrorException有几个好处:

  • 自定义的异常处理程序将使我们可以使用set_exception_handler显示漂亮的消息,甚至可以显示错误消息。
  • 它不会以任何方式破坏现有代码... trigger_error和其他错误功能仍将正常运行。
  • 很难忽略触发" E_NOTICE"和" E_WARNING"的愚蠢的编码错误。
  • 我们可以使用try/catch来包装可能产生PHP错误(不仅是异常)的代码,这是避免使用@错误抑制技巧的好方法:
try {
    $user->login();
}  catch (AuthenticationFailureException $e) {
    set_error_handler("my_login_form_handler");
    trigger_error("User could not be logged in. Please check username and password and try again!");
} catch (PersistenceException $pe) { // database unavailable
    set_error_handler("my_login_form_handler"); 
    trigger_error("Internal system error. Please contact the administrator.");
}
  • 如果我们想在发生任何未捕获的错误时向用户显示友好消息,则可以将整个脚本包装在单个" try / catch"块中。 (请仔细执行此操作,因为仅记录未捕获的错误和异常。)

代码数量不匹配