Вы можете легко сделать это с помощью __call
магического метода и универсального прокси-класса, который не наследуется напрямую от базового класса.
Вот (почти) полная реализация прокси-класса, который оборачивает любой объект, который вы передаете ему.Он будет вызывать некоторый код «до» и «после» вокруг каждого вызова метода.
class MyProxy {
function __construct($object) {
$this->object = $object;
}
function __call($method, $args) {
// Run before code here
// Invoke original method on our proxied object
call_user_func_array(array($this->object, $method), $args);
// Run after code here
}
}
$base = new BaseClass();
$proxy = new MyProxy($base);
$proxy->doSomething(); // invoke $base->doSomething();
Вы, конечно, захотите добавить немного обработки ошибок, например, запросить прокси-объект, отвечает ли он на данныйметод в __call
и выдача ошибки, если это не так.Вы даже можете создать класс Proxy, который будет базовым классом для других прокси.Дочерние прокси-классы могут реализовывать before
и after
методы.
Недостатком является то, что ваш «дочерний класс» больше не реализует BaseClass
, то есть, если вы используете type-hinting и хотят требовать, чтобы в функцию передавались только объекты типа BaseClass
, этот подход потерпит неудачу.