How do I add a new method to an object "on the fly"?
$me= new stdClass;
$me->doSomething=function ()
{
echo 'I\'ve done something';
};
$me->doSomething();
//Fatal error: Call to undefined method stdClass::doSomething()
How do I add a new method to an object "on the fly"?
$me= new stdClass;
$me->doSomething=function ()
{
echo 'I\'ve done something';
};
$me->doSomething();
//Fatal error: Call to undefined method stdClass::doSomething()
To see how to do this with eval, you can take a look at my PHP micro-framework, Halcyon, which is available on github. It's small enough that you should be able to figure it out without any problems - concentrate on the HalcyonClassMunger class.
You can harness __call
for this:
class Foo
{
public function __call($method, $args)
{
if (isset($this->$method)) {
$func = $this->$method;
$func();
}
}
}
$foo = new Foo();
$foo->bar = function () { echo "Hello, this function is added at runtime"; };
$foo->bar();
Update: The approach shown here has a major shortcoming: The new function is not a fully qualified member of the class;
$this
is not present in the method when invoked this way. This means that you would have to pass the object to the function as a parameter if you want to work with data or functions from the object instance! Also, you will not be able to accessprivate
orprotected
members of the class from these functions.
Good question and clever idea using the new anonymous functions!
Interestingly, this works: Replace
$me->doSomething(); // Doesn't work
by call_user_func on the function itself:
call_user_func($me->doSomething); // Works!
what doesn't work is the "right" way:
call_user_func(array($me, "doSomething")); // Doesn't work
if called that way, PHP requires the method to be declared in the class definition.
Is this a private
/ public
/ protected
visibility issue?
Update: Nope. It's impossible to call the function the normal way even from within the class, so this is not a visibility issue. Passing the actual function to call_user_func()
is the only way I can seem to make this work.
There's a similar post on stackoverflow that clears out that this is only achievable through the implementation of certain design patterns.
The only other way is through the use of classkit, an experimental php extension. (also in the post)
Yes it is possible to add a method to a PHP class after it is defined. You want to use classkit, which is an "experimental" extension. It appears that this extension isn't enabled by default however, so it depends on if you can compile a custom PHP binary or load PHP DLLs if on windows (for instance Dreamhost does allow custom PHP binaries, and they're pretty easy to setup).