在PHP中,有一种方法可以避免在一个类的多个方法中重复相同的try/catch代码?

问题描述:

我一直在寻找一个已经存在的问题,但是我没有找到任何问题来问我想要弄清楚什么。我能找到的最类似的问题是:php 5.3 avoid try/catch duplication nested within foreach loop (code sandwich)在PHP中,有一种方法可以避免在一个类的多个方法中重复相同的try/catch代码?

好的,我工作的地方有一个带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每个方法。有没有一种方法可以实现这种行为,所以我不必拥有所有这些具有重复代码的方法?或者我想错误处理错误?

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

你看过写一个自定义异常处理程序,并使用set_exception_handler

你在做什么似乎有点像重新发明轮子。该异常是否已经没有您在跟踪中收集的信息?参见:Exception::getTrace

也许buildErrorMessage做的更多?无论如何,我假设一个自定义的异常处理程序就是你所追求的。

+0

我认为这可能是获得我要找的东西的最好方法。谢谢! –

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

要记录正确的类和方法,我需要debug_backtrace()函数。有关更多信息,请参阅此answer

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

<?php 

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

或者只是在操作方法体的开头调用它。在类中保持这种类型的配置将有助于提高可读性。不像python示例那样整洁,但比配置文件中的某处更好。

通过使用其他人提到的set_exception_handler,可以在php中实现更一般的错误处理程序。

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