Question

If I have a class like:

class MyClass
{
   public function foo() 
   {
      echo "foo";
   }
}

And then outside of the class instantiate it and try to create an anonymous function in it:

$mine = new MyClass();

$mine->bar = function() {
   echo "bar";
}

And then try to call it like $mine->bar(), I get:

Fatal error: Call to undefined method MyClass::bar() in ...

How can I create an anonymous function / closure on a class instance?

Aside: Before you tell me I should rethink my logic or use interfaces and OOP properly, in my case, it's a convenience method that applies to this specific instance of a bastardized class in an attempt to clean-up a legacy procedural application. And yes, I'm using PHP 5.3+

Was it helpful?

Solution

See my blog article here: http://blog.flowl.info/2013/php-container-class-anonymous-function-lambda-support/

You need to add a magic __call function:

public function __call($func, $args) {
    return call_user_func($this->$func, $args);
}

The problem is that within this construct you can call private methods from public scope. I suggest not to simply add new variables to a class that are not defined. You can avoid this using magic __set functions and catch all undefined variables in a container (= array, like in my blog post) and change the call_user_func behaviour to call only inside the array:

// inside class:
public $members = array();

public function __call($func, $args) {
    // note the difference of calling only inside members:
    return call_user_func($this->members[$func], $args);
}

OTHER TIPS

__call

This will work.

class Foo {

    public $bar;
    public function __construct()
    {
        $this->bar = function()
        {
            echo 'closure called';
        };

        $this->bar();
    }

    public function __call($method, $args) {
        return call_user_func($this->$method, $args);
    }

}

new Foo();

The function IS being created. PHP has a problem with calling it.

Dirty, but works:

$f = $mine->bar;
$f();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top