【问题标题】:When to use Try Catch blocks何时使用 Try Catch 块
【发布时间】:2011-07-09 02:54:12
【问题描述】:

好的,这可能是一个非常菜鸟的问题,但我发现关于这方面的 PHP 文档和几个 Internet 搜索并没有给我任何想法。

我什么时候应该使用 try-catch 块来改进我的应用程序?

我读到有人说我们应该只使用 try-catch 块来防止致命错误。 我读到其他人说我们应该只在意外错误上使用它(等待什么?意外?如果它们是意外错误,我怎么能用 try-catch 防止它们?我应该把我所有的应用程序代码放在一个 try 块中吗?)。 其他人只是说 try-catch 块应该在任何地方使用,因为它们也可以扩展(扩展 Exception 类)。 最后有人说 PHP 的 try-catch 块完全没用,因为它们的实现非常糟糕。 (在这个问题上,我发现了一个关于性能的很好的 SO 问题)。

在我看来,这个话题非常奇怪和困惑。有人可以点亮我吗?

【问题讨论】:

  • 这正是这类问题对 SO 不利的原因。这一切都取决于偏好。严格的 OOP 资深人士会到处告诉你,而严格的程序资深人士会告诉你,嘿,他们很愚蠢。做对你有用的事。
  • 但这并不是严格意义上的偏好或适当性。在 PHP 中,有些函数会产生错误,有些会产生异常(有些甚至只是打印一些东西,或者有自定义消息假脱机程序)。这取决于您使用的功能。一些扩展(如 PDO)甚至可以配置为打印错误消息或抛出异常。
  • @Kevin Peno,我认为那里有一些隐藏的模式在谈论它。
  • 我是从一般的角度说的。如果你想让我把它放在 PHP 的角度。思想严谨的 OOP 资深人士会告诉您将异常放在任何地方,但不要放在那里,或放在那里,或放在那里,或放在那里……因为 PHP 对于它在哪里抛出错误(或者我应该说打印它们)是愚蠢的。

标签: php try-catch


【解决方案1】:

在我看来,这个话题非常奇怪和困惑。有人可以点亮我吗?

当然。我不是 PHP 用户,但在使用过 ActionScript、Java 和 JavaScript 中的 try/catch 之后,我可能会有一点见解。但请记住,不同的语言和平台鼓励使用不同的 try/catch。那就是……

我建议使用 try/catch 的唯一情况是,如果您使用的是本地语言函数,

  1. 可能引发错误/异常
  2. 不会为您提供任何工具来检测您是否要执行会导致错误/异常的愚蠢行为。例如:在 ActionScript 中,关闭未打开的加载程序会导致错误,但加载程序没有要检查的 isOpen 属性,因此您不得不将其包装在 try/catch 中以消除其他完全无意义的错误。
  3. 错误/异常真的毫无意义。

让我们看看您列出的示例,看看它们与该列表的关系如何。

我读到有人说我们应该只使用 try-catch 块来防止致命错误。

对于 AS 的 loader.close() 函数,这是个好建议。这是一个致命的错误,而这一切都源于一个微不足道的失误。另一方面,几乎所有 AS 中的错误都会导致您的应用程序停止运行。然后你会把它们都包装在 try/catch 中吗?绝对不! “致命错误”之所以致命是有原因的。这意味着发生了一些非常错误的事情,并且让应用程序继续在潜在的“未定义”状态下运行是鲁莽的。最好知道发生了错误,然后修复它,而不是放任不管。

我读到其他人说我们应该只在出现意外错误时使用它

那就更糟了。这些正是你不想让他们沉默的错误,因为让他们沉默意味着你永远不会找到它们。不过,也许你没有吞下它们……也许你正在记录它们。但是你为什么要尝试/捕获/记录/继续,就好像什么都没发生一样,让程序在潜在的危险和意外情况下运行呢?只是让错误把你踢到牙齿,然后修复它。没有什么比尝试调试其他人编写的程序中的错误更令人沮丧的了,因为他们将所有内容都包装在 try/catch 块中,然后忽略了记录。

其他人只是说应该在任何地方使用 try-catch 块,因为它们也可以扩展(扩展 Exception 类)。

如果您是进行投掷的人,并且您正试图提醒自己注意程序中的异常情况,那么这样做有潜在的好处......但是为什么要尝试/捕获您自己的抛出错误呢?让它踢你的牙齿,然后修复它,这样你就不需要再抛出错误了。

最后有人说 PHP 的 try-catch 块完全没用,因为它们的实现非常糟糕。 (在这我发现一个关于性能的好问题)。

也许是这样。不过我无法回答这个问题。

所以...这可能是一个宗教问题,我敢肯定人们会不同意我的观点,但从我的特殊角度来看,这些是我多年来从 try/catch 中学到的教训。

【讨论】:

  • 您提倡先看再跳跃的方法。也就是说,您在调用函数之前尝试确定函数是否会成功。但是,导致和捕获错误的代码通常比您的方法更干净、更有效。当然,这在很大程度上取决于语言实现决策。
  • +1 给你。语言和实现肯定会影响这一点。有时 try/catch 有更干净的感觉。另一方面,显式捕获十几个潜在异常可能会影响编码人员简单地吞下并忘记它们(我认为这是 try/catch 最致命的方面,也是其剑的“另一边”)。不过,从性能的角度来看,try/catch 是 ActionScript 中的一条狗(这是我最常使用的),因此也取决于平台和语言。
  • 我们不要责怪程序员破坏了异常和 try/catch 块的想法。仅仅因为人们愚蠢地实施它们,并不意味着它们有缺陷。
  • 唯一一种我见过的程序员倾向于在其他语言中吞下 Java 中的异常(感谢检查的异常) 糟糕的程序员似乎只是让异常杀死程序。
  • 我认为糟糕的编码器(或者充其量是时间太少无法正确解决问题的编码器)是不知道如何解决问题并使用 try/赶上只是把工作推到门外。异常会提醒您一个事实,即您首先遇到了问题,并且代码需要重新考虑它是否能够经得起现实世界的使用,那么为什么要纸上谈兵呢?无论您是在程序崩溃中还是在错误日志中了解这些异常,只要异常最终使您解决了问题,它就可以达到目的。
【解决方案2】:

不同的人会告诉你不同的事情。但这就是我的想法,特别是在 Web 应用程序的情况下。

您的整个页面应该在向用户显示错误消息的 try/catch 中。错误消息不应详细告诉用户发生了什么,因为这是一个安全问题。它应该将有关错误的信息记录到日志文件中。

另一种情况是事务的正常运行可能出现问题。 PHP 并不是很高兴,所以这可能不会发生太多。基本上,如果您遇到一个在失败时抛出异常的函数,您可以捕获该异常并在这种情况下执行其他操作。

一般来说,您的问题就像是在询问您将如何使用锤子来提高房屋的质量。使用异常来帮助您实现特定的行为。不要寻找使用异常的地方。

【讨论】:

  • 我感觉就像在 PHP 的 set_error_handler() 上作弊,只是将我所有的应用程序脚本放在一个 try 块中。但是,您让我了解了 try-blocks 的实际用途。
  • 好点。您可能不希望用户看到“真实的”错误消息。在这种情况下,捕捉和重新投掷可能很有价值。
  • @Charlie:再次。有错误消息异常。两种不同的东西。错误处理程序仅适用于错误消息。异常需要单独的 try/catch 块。
  • 将整个页面包装在 try/catch 块中对用户来说似乎不是最好的体验。也许页面的一小部分失败了,但这并不意味着整个页面都没用。在安全方面,应该实现一个错误记录系统,向用户显示友好的错误(例如:'对不起,出了点问题。')并将真正的错误消息保存到日志文件中。
  • @bart,当然你可以将你的网页分成几部分,这样某些部分可以工作,而其他部分不能。但是,要正确完成不应该发生的事情,需要付出更多的努力。
【解决方案3】:

我认为这只是偏好问题,但根据我的经验,我鼓励您尽可能多地使用它们。

在我们目前在工作中开发的应用程序中(如果需要,使用 Zend 框架),我们使用一个 try..catch 块来捕获整个应用程序中的所有异常,这些异常会显示给用户,例如错误 500 和异常是将更多信息记录到数据库中。在 PHP 应用程序的情况下,我个人喜欢这种方法,因为异常是可扩展的,并且您基本上可以编写您需要的任何功能。

【讨论】:

  • 这与我自己对 try/catch 的批评形成了很好的对比。通过允许用户查看错误代码来向用户显示有关服务器内部工作的原始数据可能很危险,并且再次显示了上下文和语言因素对这个问题的影响程度。
  • 有趣的想法 - 尝试一下
【解决方案4】:

我主要在数据库调用周围使用 Try/Catch...尤其是输入、更新和删除等。

我有时会在复杂的数据处理中使用它来处理数组和循环,使用动态数据和数组,其中可能会出错,即:缺少数组元素或其他东西(不过我通常会检查类似的东西)。

我还将它们用于我无法完全控制的操作,例如从可能存在数据问题的外部或外部数据源导入数据或访问源文件。

我认为“意外错误”的含义是您无法通过良好的编程实践来预防问题,例如在“包含”文件之前检查文件是否存在,您可以预料到一些问题,因此请使用良好的实践来防止它们.不要只是通过将它们包装在 try/catch 中来让它们碰运气。

请改用良好的编程实践,因为您应该在任何地方都这样做。不要使用 try/catch 作为任何地方的懒惰快捷方式。这太夸张了。

【讨论】:

    【解决方案5】:

    我同意@scriptocalypse。事实上,我只在 2 种情况下使用 PHP 中的 try/catch 块。

    1. 如果可能发生一些外部(不在我的代码内部)问题或数据库错误:

      • 从其他来源(例如curl)获取数据
      • 从文件中获取数据
      • 数据库异常
    2. 如果我在另一个系统(如 CMS 或类似系统)中工作,并且我想覆盖某个行为。例如,我不希望抛出异常但将异常消息返回到视图。

    【讨论】:

      【解决方案6】:

      你不能到处放 try catch 块。

      但是,在应用程序测试期间,生成的异常应该会提醒您需要尝试捕获的地方。这是您应该对应用程序/代码进行彻底测试的原因之一。

      如果你看到一个你认为需要它的地方,我会放一个。

      编辑:好的,您可以将它们放在任何地方,但您需要了解将它们放在代码中的什么位置。

      【讨论】:

      • 你为什么不能?在 PHP 中,对异常的唯一限制是停止错误(致命、解析等)。
      • @Kevin,您可以将 try/catch 放在任何地方,但这确实违背了首先出现异常的目的。
      • @Winston 不要太从字面上理解我。我只是反驳说你确实可以把 then 放在任何地方。
      【解决方案7】:

      我通常将 Try and Catch 放在代码中我无法控制的外力作用的区域周围。例如,打开和读取外部文件..您无法控制在读取文件的某个时刻,文件损坏或发生其他您无法控制的事情,例如文件服务器 dc 或其他东西

      【讨论】:

        猜你喜欢
        • 2010-12-15
        • 2019-12-04
        • 1970-01-01
        • 1970-01-01
        • 2012-03-04
        • 1970-01-01
        • 2016-05-21
        • 1970-01-01
        • 2016-05-04
        相关资源
        最近更新 更多