简体   繁体   中英

Access instance of class in callback anonymous function

I have a class with a few methods that take an anonymous function as a parameter. The class looks like this:

class MyClass {
    public function myMethod($param, $func) {
           echo $param;
           user_call_func($func);
    }


    public function sayHello() {
        echo "Hello from MyClass";
    }
}

I'd like to be able to do things like this:

$obj = new MyClass;
$obj->myMethod("Hi", function($obj) {
    echo "I'm in this anonymous function";
    // let's use a method from myClass
    $obj->sayHello();
});

So, in my anonymous function, since I passed $obj as a parameter to the anonymous function, I should be able to access its methods from within the anonymous function. In this case we'd see

I'm in this anonymous function
Hello from MyClass

How would I achieve this?

Thanks

Use the use construct:

$self = $this;
$obj->myMethod("Hi", function($obj) use($self) {
    echo "I'm in this anonymous function";
    // let's use a method from myClass
    $obj->sayHello();
});

You've got to capture $this in another variable because use doesn't allow $this to be passed in, unless you are using PHP >= 5.4. Relevant quote from the documentation :

Closures may also inherit variables from the parent scope. Any such variables must be passed to the use language construct. Inheriting variables from the parent scope is not the same as using global variables. Global variables exist in the global scope, which is the same no matter what function is executing. The parent scope of a closure is the function in which the closure was declared (not necessarily the function it was called from).

Update

It may also be helpful to know that you retain the visibility of the class that you're currently in when the anonymous function is executing, as demonstrated in this simple script:

class Test
{
    public function testMe()
    {
        $self = $this;
        $tester = function() use($self) {
            $self->iAmPrivate();
        };

        $tester();
    }

    private function iAmPrivate()
    {
        echo 'I can see my own private parts!';
    }
}

$test = new Test;
$test->testMe();

Output:

I can see my own private parts!

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