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

时间:2017-10-04 21:39:51

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

我一直在寻找已经问过这个问题的现有问题,但是我无法找到任何问题,这些问题可以解释我想要解决的问题。我能找到的最相似的问题是: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中包装每个方法。有没有办法实现这种行为所以我不必拥有所有这些重复代码的方法?或者我是否错误地考虑错误处理?

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

3 个答案:

答案 0 :(得分:1)

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

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

也许buildErrorMessage做得更多?无论如何,我假设您正在使用自定义异常处理程序。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

这样的东西
me

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

可以使用其他人提到的<?php class MyController extends Controller { function __construct() { $this->setActionErrorHandler('function_name', 'handler'); } } 在php中实现更多通用错误处理程序。

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