简体   繁体   中英

PHP Closure On Class Instance

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+

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);
}

__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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM