简体   繁体   English

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

[英]In PHP is there a way I can avoid repeating the same try / catch code in multiple methods of a class?

I've been searching for an existing question that already asks this, but I wasn't able to find any questions that quite ask what I'm trying to figure out.我一直在寻找一个已经提出这个问题的现有问题,但我找不到任何能很好地询问我想要弄清楚的问题的问题。 The most similar question I could find was this: php 5.3 avoid try/catch duplication nested within foreach loop (code sandwich)我能找到的最相似的问题是: php 5.3 避免嵌套在 foreach 循环中的 try/catch 重复(代码三明治)

Okay so the place I work at has a web application with a PHP back end.好的,所以我工作的地方有一个带有 PHP 后端的 Web 应用程序。 We use an MVC type structure.我们使用 MVC 类型的结构。 I'm writing a controller that has multiple methods and in each of my methods I'm wrapping my code with identical try / catch code.我正在编写一个具有多个方法的控制器,并且在我的每个方法中,我都使用相同的 try/catch 代码包装我的代码。 In the catch, I pass the exception, a reference to the class, and a reference to the function to a method that builds an error message so that the error messages are formatted the same across the application.在 catch 中,我将异常、对类的引用和对函数的引用传递给构建错误消息的方法,以便在整个应用程序中错误消息的格式相同。 It looks something this:它看起来像这样:

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);
        }
    }

}

So the buildErrorMessage function prevents each method from repeating the code that formats the error message, but there is something that really bothers me about have the same code spread through out every method in the class.所以 buildErrorMessage 函数可以防止每个方法重复格式化错误消息的代码,但是有一些事情让我真正困扰,因为在类中的每个方法中都有相同的代码。 I know that PHP doesn't support python-like decorator syntax, but just to demonstrate what I'm envisioning conceptually;我知道 PHP 不支持类似 python 的装饰器语法,但只是为了演示我在概念上的设想; I want the code to behave something more like this:我希望代码的行为更像这样:

class MyController {

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

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

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

}

Where the @DefaultErrorHandling decorator would wrap each method in that standard try / catch. @DefaultErrorHandling 装饰器将每个方法包装在标准的 try / catch 中。 Is there a way I could achieve this behavior so I don't have to have all of these methods that have repeated code?有没有办法可以实现这种行为,这样我就不必拥有所有这些具有重复代码的方法? Or am I thinking about error handling incorrectly?还是我在考虑错误处理?

Thanks to anyone who takes the time to answer this.感谢任何花时间回答这个问题的人。

Have you looked at a writing a custom exception handler and using set_exception_handler ?您是否看过编写自定义异常处理程序并使用set_exception_handler

What you are doing seems a bit like reinventing the wheel.你在做什么似乎有点像重新发明轮子。 Does the Exception not already have the info you are collecting in the trace?异常是否还没有您在跟踪中收集的信息? See: Exception::getTrace请参阅:异常::getTrace

Maybe buildErrorMessage does more?也许buildErrorMessage做得更多? Anyway, I assume a custom exception handler is what you are after.无论如何,我假设自定义异常处理程序是您所追求的。

Not sure if there is a better way to solve this or not, but I created a logging class that formatted the log for me.不确定是否有更好的方法来解决这个问题,但我创建了一个日志类来为我格式化日志。 Then just called this in my catch block.然后在我的 catch 块中调用它。

To log the correct Class and Method, I the debug_backtrace() function.要记录正确的类和方法,我使用debug_backtrace()函数。 See this answer for more information.有关更多信息,请参阅此答案

Entry point that calls controller methods can wrap those calls with try / catch.调用控制器方法的入口点可以用 try / catch 包装这些调用。 That being said, if you are planning to use different type of error handlers on those methods then you can implement something in your base controller (or use trait) that keeps track of which handler should be invoked on each particular method.话虽如此,如果您计划在这些方法上使用不同类型的错误处理程序,那么您可以在您的基本控制器(或使用特征)中实现一些内容,以跟踪应该在每个特定方法上调用哪个处理程序。 Something like就像是

<?php

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

Or just call it at the beginning of action method body.或者只是在操作方法主体的开头调用它。 Keeping this type of configuration within class itself will help with readability.在类本身中保留这种类型的配置将有助于提高可读性。 Not as neat as python example but better than somewhere in configuration files.不像 python 示例那么简洁,但比配置文件中的某个地方更好。

More generic error handlers can be implemented in php by using set_exception_handler mentioned by others.可以使用其他人提到的set_exception_handler在 php 中实现更通用的错误处理程序。

I'm not really getting why there is such a requirement.我真的不明白为什么有这样的要求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM