Вы можете воспользоваться методом __call
для перенаправления несуществующих вызовов методов. Добавьте реестр в свой класс, чтобы вы могли добавлять / удалять методы на лету. Соглашение о вызове для внешней функции заключается в том, что первым параметром является объект, с которым связана функция.
clas Foo {
private $registry;
public function __call($alias, $args) {
if (array_key_exists($alias, $this->registry)) {
// prepend list of parameters with $this object
array_unshift($args, $this);
return call_user_func_array($this->registry[$alias], $args)
}
}
public function register($method, $alias = null) {
$alias or $alias = $method; // use original method name if no alias
$this->registry[$alias] = $method;
}
public function unregister($alias) {
unset($this->registry[$alias]);
}
}
Представьте себе функцию clone_object
, которая возвращает массив клонированных объектов. Первый параметр - это объект, который нужно клонировать, а второй - количество клонов.
function clone_object($foo, $n) {
$a = array();
while ($n--) {
$a[] = clone $foo;
}
return $a;
}
Теперь, таким образом, вы можете внедрить метод clone_object
в класс Foo
и дать ему псевдоним bar
:
$f = new Foo();
$f->register('clone_object', 'bar');
$f->bar(5); // this will return array of 5 cloned objects
В последней строке вызов метода bar
вызовет перенаправление на функцию clone_object
. Помните, что соглашение о вызовах будет вставлять параметр $this
в список параметров, поэтому (5)
будет изменено на ($this, 5)
.
Предупреждение: внешние функции не могут работать с закрытыми / защищенными свойствами и методами.
Просто последнее слово, если вы можете придумать решение, которое не меняет объекты на лету, вы, вероятно, должны его использовать. Выше приведено чёрное волшебство, и его следует использовать с особой осторожностью.