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()
для перехвата и пересылки вызовов метода к цели.
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
Таким образом, это будет выводить исключение второго класса, обработанное вашим первым обработчиком класса.
Надеюсь, это поможет !