How to add a new method to a php object on the fly?
You can harness __call
for this:
class Foo{ public function __call($method, $args) { if (isset($this->$method)) { $func = $this->$method; return call_user_func_array($func, $args); } }}$foo = new Foo();$foo->bar = function () { echo "Hello, this function is added at runtime"; };$foo->bar();
With PHP 7 you can use anonymous classes, which eliminates the stdClass
limitation.
$myObject = new class { public function myFunction(){}};$myObject->myFunction();
Using simply __call in order to allow adding new methods at runtime has the major drawback that those methods cannot use the $this instance reference.Everything work great, till the added methods don't use $this in the code.
class AnObj extends stdClass{ public function __call($closure, $args) { return call_user_func_array($this->{$closure}, $args); } } $a=new AnObj(); $a->color = "red"; $a->sayhello = function(){ echo "hello!";}; $a->printmycolor = function(){ echo $this->color;}; $a->sayhello();//output: "hello!" $a->printmycolor();//ERROR: Undefined variable $this
In order to solve this problem you can rewrite the pattern in this way
class AnObj extends stdClass{ public function __call($closure, $args) { return call_user_func_array($this->{$closure}->bindTo($this),$args); } public function __toString() { return call_user_func($this->{"__toString"}->bindTo($this)); }}
In this way you can add new methods that can use the instance reference
$a=new AnObj();$a->color="red";$a->sayhello = function(){ echo "hello!";};$a->printmycolor = function(){ echo $this->color;};$a->sayhello();//output: "hello!"$a->printmycolor();//output: "red"