Bueno, una forma, sería hacer todo el método llama "virtual":
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";
}
Todo PHP:
$foo->addOverride('doSomething', $f);
$foo->doSomething('test'); // Bar: Foo: test Baz
Se pasa la instancia del objeto como el primer método para la "override". Nota: Este método "anulado" no tendrá acceso a ningún miembro protegido de la clase. Así que use getters (__get
, __set
). Se tendrá acceso a métodos protegidos, ya que la llamada real viene de __call()
...
Nota: Tendrá que modificar todos los métodos por defecto a un prefijo de declaración '_' para que esto funcione. .. (o puede elegir otra opción de prefijo, o puede simplemente delimitarlos todos protegidos) ...
No creo que lo que quieres sea posible. Podría estar equivocado, pero en general * Las API de Reflexión * se usan para ** obtener ** información sobre clases, etc. y no para cambiar el código en tiempo de ejecución. –
da más información sobre lo que estás tratando de hacer y tal vez podamos ayudar a encontrar una solución diferente – Galen
Aunque estoy seguro de que hay una solución a esto, y que sabes que la necesitas, ¿estás seguro de que es lo que quieres? ¿Por qué querrías cambiar la naturaleza de una función durante el tiempo de ejecución? Una mejor opción podría ser pasar una variable que controla el flujo de funciones; o tal vez considere usar sentencias eval() para ejecutar código. Piénselo de esta manera: ¿cómo se nombra una función que no tiene un efecto predecible? – Kurucu