Ну, одним из способов было бы сделать все вызовы методов "виртуальными":
class Foo {
protected $overrides = array();
public function __call($func, $args) {
$func = strtolower($func);
if (isset($this->overrides[$func])) {
// We have a override for this method, call it instead!
array_unshift($args, $this); //Add the object to the argument list as the first
return call_user_func_array($this->overrides[$func], $args);
} elseif (is_callable(array($this, '_' . $func))) {
// Call an "internal" version
return call_user_func_array(array($this, '_' . $func), $args);
} else {
throw new BadMethodCallException('Method '.$func.' Does Not Exist');
}
}
public function addOverride($name, $callback) {
$this->overrides[strtolower($name)] = $callback;
}
public function _doSomething($foo) {
echo "Foo: ". $foo;
}
}
$foo = new Foo();
$foo->doSomething('test'); // Foo: test
PHP 5.2:
$f = create_function('$obj, $str', 'echo "Bar: " . $obj->_doSomething($str) . " Baz";');
PHP 5.3:
$f = function($obj, $str) {
echo "Bar: " . $obj->_doSomething($str) . " Baz";
}
Все PHP:
$foo->addOverride('doSomething', $f);
$foo->doSomething('test'); // Bar: Foo: test Baz
Он передает экземпляр объекта в качестве первого метода для «переопределения».Примечание. Этот переопределенный метод не будет иметь доступа ни к каким защищенным членам класса.Так что используйте геттеры (__get
, __set
).Он будет иметь доступ к защищенным методам, так как фактический вызов поступает с __call()
...
Примечание: Вам нужно будет изменить все ваши методы по умолчанию, добавив префикс'_' для того, чтобы это работало ... (или вы можете выбрать другой параметр префикса, или вы можете просто ограничить область их защиты) ...