What's the best way to do something like this in PHP?:
$a = new CustomClass();
$a->customFunction = function() {
return 'Hello World';
}
echo $a->customFunction();
(The above code is not valid.)
What's the best way to do something like this in PHP?:
$a = new CustomClass();
$a->customFunction = function() {
return 'Hello World';
}
echo $a->customFunction();
(The above code is not valid.)
Here is a simple and limited monkey-patch-like class for PHP. Methods added to the class instance must take the object reference ($this
) as their first parameter, python-style.
Also, constructs like parent
and self
won't work.
OTOH, it allows you to patch any callback type into the class.
class Monkey {
private $_overload = "";
private static $_static = "";
public function addMethod($name, $callback) {
$this->_overload[$name] = $callback;
}
public function __call($name, $arguments) {
if(isset($this->_overload[$name])) {
array_unshift($arguments, $this);
return call_user_func_array($this->_overload[$name], $arguments);
/* alternatively, if you prefer an argument array instead of an argument list (in the function)
return call_user_func($this->_overload[$name], $this, $arguments);
*/
} else {
throw new Exception("No registered method called ".__CLASS__."::".$name);
}
}
/* static method calling only works in PHP 5.3.0 and later */
public static function addStaticMethod($name, $callback) {
$this->_static[$name] = $callback;
}
public static function __callStatic($name, $arguments) {
if(isset($this->_static[$name])) {
return call_user_func($this->_static[$name], $arguments);
/* alternatively, if you prefer an argument list instead of an argument array (in the function)
return call_user_func_array($this->_static[$name], $arguments);
*/
} else {
throw new Exception("No registered method called ".__CLASS__."::".$name);
}
}
}
/* note, defined outside the class */
function patch($this, $arg1, $arg2) {
echo "Arguments $arg1 and $arg2
";
}
$m = new Monkey();
$m->addMethod("patch", "patch");
$m->patch("one", "two");
/* any callback type works. This will apply `get_class_methods` to the $m object. Quite useless, but fun. */
$m->addMethod("inspect", "get_class_methods");
echo implode("
", $m->inspect())."
";