【问题标题】:In PHP is there a way I can avoid repeating the same try / catch code in multiple methods of a class?在 PHP 中有没有一种方法可以避免在一个类的多个方法中重复相同的 try/catch 代码?
【发布时间】:2018-03-16 10:11:02
【问题描述】:

我一直在寻找一个已经提出这个问题的现有问题,但我找不到任何能完全询问我想要弄清楚的问题。我能找到的最相似的问题是:php 5.3 avoid try/catch duplication nested within foreach loop (code sandwich)

好的,我工作的地方有一个带有 PHP 后端的 Web 应用程序。我们使用 MVC 类型的结构。我正在编写一个具有多种方法的控制器,并且在我的每个方法中,我都用相同的 try/catch 代码包装我的代码。在 catch 中,我将异常、对类的引用和对函数的引用传递给构建错误消息的方法,以便错误消息在整个应用程序中的格式相同。它看起来像这样:

class MyController {

    public function methodA() {
        try {
            // code for methodA
        } catch(Exception $e) {
            $errorMessage = Tasks::buildErrorMessage($e, __CLASS__, __FUNCTION__);
            throw new Exception($errorMessage);
        }
    }

    public function methodB() {
        try {
            // code for methodB
        } catch(Exception $e) {
            $errorMessage = Tasks::buildErrorMessage($e, __CLASS__, __FUNCTION__);
            throw new Exception($errorMessage);
        }
    }

    public function methodC() {
        try {
            // code for methodC
        } catch(Exception $e) {
            $errorMessage = Tasks::buildErrorMessage($e, __CLASS__, __FUNCTION__);
            throw new Exception($errorMessage);
        }
    }

}

所以 buildErrorMessage 函数可以防止每个方法重复格式化错误消息的代码,但是让我真正困扰的是,在类中的每个方法中都使用相同的代码。我知道 PHP 不支持类似 python 的装饰器语法,只是为了演示我在概念上的设想;我希望代码的行为更像这样:

class MyController {

    @DefaultErrorHandling()
    public function methodA() {
        // code for methodB
    }

    @DefaultErrorHandling()
    public function methodB() {
        // code for methodB
    }

    @DefaultErrorHandling()
    public function methodC() {
        // code for methodC
    }

}

@DefaultErrorHandling 装饰器将每个方法包装在标准的 try/catch 中。有没有办法可以实现这种行为,所以我不必拥有所有这些重复代码的方法?还是我认为错误处理不正确?

感谢任何花时间回答这个问题的人。

【问题讨论】:

    标签: php design-patterns error-handling try-catch


    【解决方案1】:

    您是否看过编写自定义异常处理程序并使用set_exception_handler

    您所做的似乎有点像重新发明轮子。异常是否还没有您在跟踪中收集的信息?见:Exception::getTrace

    也许buildErrorMessage 做得更多?无论如何,我认为自定义异常处理程序就是您所追求的。

    【讨论】:

    • 我认为这可能是获得所需内容的最佳方式。谢谢!
    【解决方案2】:

    不确定是否有更好的方法来解决这个问题,但我创建了一个日志类来为我格式化日志。然后在我的 catch 块中调用它。

    要记录正确的类和方法,我使用debug_backtrace() 函数。请参阅此answer 了解更多信息。

    【讨论】:

      【解决方案3】:

      调用控制器方法的入口点可以用 try / catch 包装这些调用。话虽如此,如果您打算在这些方法上使用不同类型的错误处理程序,那么您可以在基本控制器(或使用特征)中实现一些东西,以跟踪应该在每个特定方法上调用哪个处理程序。类似的东西

      <?php
      
      class MyController extends Controller
      {
          function __construct()
          {
              $this->setActionErrorHandler('function_name', 'handler');
          }
      }
      

      或者只是在动作方法体的开头调用它。在类本身中保留这种类型的配置将有助于提高可读性。不像 python 示例那么简洁,但比配置文件中的某个地方要好。

      使用别人提到的set_exception_handler可以在php中实现更通用的错误处理程序。

      我真的不明白为什么会有这样的要求。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-11
        相关资源
        最近更新 更多