Reputation: 167
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
Upvotes: 1
Views: 408
Reputation: 24661
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!
Upvotes: 5