PHP Try Catch для всего класса

простой вопрос, но, похоже, не может найти ответ.

Если у меня есть класс php, можно ли зарегистрировать обработчик исключений для всего класса?

Почему я хочу сделать это заключается в том, что мой класс использует объекты, которые являются частью моей модели предметной области. Эти методы объекта создают очень явные исключения. Я не хочу, чтобы эти исключения пузырились до классов более высокого уровня, но вместо этого хочу поймать все эти исключения и выбросить их как более общее исключение например, DomainLayerException

поэтому я хотел бы, чтобы одна область в моем классе, которая ловит любое количество списка исключений, которые я определяю из моей модели домена, и выбрасывает их как более общее исключение, например

В настоящее время я делаю это путем обертывания вызовов метода к объектам домена в блоке try catch. Это становится очень грязным, поскольку я использую все больше и больше объектов домена и их методов. Было бы здорово, чтобы удалить эти блоки try catch и обрабатывать их все в одном месте в классе, т. е. если в классе возникает исключение, оно перехватывается одним обработчиком событий, определенным в классе

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() magic метод для перехвата и переадресации вызовов метода к цели.


EDIT: похоже, это плохая идея, так как "set_exception_handler-глобальный метод. Может закончиться целым миром проблем, если множество классов устанавливают себя в качестве глобального обработчика". Спасибо @Gaz_Edge за указание на это.

вместо этого вы должны посмотреть на Джек.


Если бы я понял, что вы хотели, я думаю, вы можете использовать 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

Как это, это выведет ваше исключение второго класса, обработанное вашим обработчиком первого класса.

надеюсь, что это помогает !