【问题标题】:PHP Try Catch for Entire ClassPHP Try Catch 整个类
【发布时间】:2014-08-24 12:17:48
【问题描述】:

简单的问题,但似乎找不到答案。

如果我有一个php类,是否可以为整个类注册一个异常处理程序?

我想这样做的原因是我的类使用了属于我的域模型的对象。这些对象的方法抛出非常明确的异常。我不希望这些异常冒泡到更高级别的类,而是希望捕获所有这些异常并将它们作为更一般的异常抛出,例如域层异常

因此,我希望我的班级中有一个区域可以捕获我从域模型中定义的任意数量的异常列表,并将它们作为更一般的异常抛出,例如

目前我这样做的方法是将对域对象的方法调用包装在 try catch 块中。随着我使用越来越多的域对象及其方法,这变得非常混乱。删除这些 try catch 块并在类中的一个位置处理它们会很棒,即如果在类中抛出任何异常,它会被类中定义的单个事件处理程序捕获

【问题讨论】:

    标签: php exception exception-handling php-5.4


    【解决方案1】:

    编辑:这似乎是一个坏主意,因为“set_exception_handler 是一种全局方法。如果许多类都将自己设置为全局处理程序,最终可能会陷入困境”。感谢@Gaz_Edge 指出。

    您应该查看Jack's answer


    如果我明白你想要什么,我想你可以在课堂上使用set_exception_handler

    例子:

    class myClass {
        public function __construct() {
            set_exception_handler(array('myClass','exception_handler'));
        }
    
        public function test(){
            $mySecondClass = new mySecondClass();
        }
    
        public static function exception_handler($e) {
            print "Exception caught in myClass: ". $e->getMessage() ."\n";
        }
    }
    
    class mySecondClass{
        public function __construct() {
            throw new Exception('Exception in mySecondClass');
        }
    }
    
    $myClass = new myClass();
    $myClass->test();
    

    那就是:Exception caught in myClass: Exception in mySecondClass

    像这样,这将输出由您的第一个 Class 处理程序处理的第二个 Class 异常。

    希望对你有帮助!

    【讨论】:

    • 感谢您的回答。问题在于 set_exception_handler 是一个全局方法。如果很多类都将自己设置为全局处理程序,那么最终可能会陷入困境
    • @Gaz_Edge 绝对正确,这样使用它不是一个好主意。最好有 Jack 描述的代理方法。
    【解决方案2】:

    您可以使用代理类代表您执行调用并让您包装异常:

    class GenericProxy
    {
        private $obj;
        private $handler;
    
        public function __construct($target, callable $exceptionHandler = null)
        {
            $this->obj = $target;
            $this->handler = $exceptionHandler;
        }
    
        public function __call($method, $arguments)
        {
            try {
                return call_user_func_array([$this->obj, $method], $arguments);
            } catch (Exception $e) {
                // catch all
                if ($this->handler) {
                    throw call_user_func($this->handler, $e);
                } else {
                    throw $e;
                }
            }
        }
    }
    
    $proxy = new GenericProxy($something, function(Exception $e) {
        return new MyCoolException($e->getMessage(), $e->getCode(), $e);
    });
    echo $proxy->whatever_method($foo, $bar);
    

    它使用__call()魔术方法来拦截并将方法调用转发到目标。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-06
      • 2012-09-04
      • 2015-03-31
      • 1970-01-01
      • 1970-01-01
      • 2017-09-11
      相关资源
      最近更新 更多