PHP尝试捕获整个类

时间:2014-07-03 11:32:27

标签: php exception exception-handling php-5.4

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

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

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

因此,我希望我的班级中的一个区域能够捕获我从域模型中定义的任意数量的例外列表,并将它们作为更一般的例外情况抛出,例如。

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

2 个答案:

答案 0 :(得分:11)

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

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()魔术方法拦截并转发对目标的方法调用。

答案 1 :(得分:0)

编辑:看起来这是一个坏主意,因为" set_exception_handler是一个全局方法。如果很多课程将自己设定为全球处理程序,那么最终可能会陷入困境。#34;。感谢@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

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

希望它有所帮助!