PHP function returning anonymous function with use / global

I am new to PHP and currently learning the concept of closure.

For closure using use() I know that I can do the following:

$y = "hello"; 
$c = function() use ($y) {
    return $y; 
}; 

print_r($c()); // prints out 'hello'
echo '<br />'; 

However, I have problem on doing a function that returns another anonymous function, for example:

$u = function() {
    return function () use ($y) {
        return $y; 
    }; 
}; 

print_r($u()); // empty closure object...
echo '<br />'; 

I know that when I modify the above codes to the below one, then the code works perfectly. BUT I do NOT understand the reason why. Hope someone can explain it to me. Thanks.

$b = function() use ($y) {
    return function () use ($y) {
        return $y; 
    };
}; 

print_r($b()); // output :  [y] => hello
echo'<br />'; 

In a similar way, I have a question on the below code using global, why it does not work:

$k = function() {
    return function() {
        global $y; 
        return $y; 
    }; 
}; 

print_r($k()); // prints out 'Closure Object ( )'
echo '<br />'; 

Please do NOT tell me how to swap the codes to make it work. As I have tried, and I know how to change and make these codes work. Instead, I would like to know why global and use() does NOT work when I call them in the return of another anonymous function.

Thanks for helping me to clarify the idea on how use / global works.


I know that when I modify the above codes to the below one, then the code works perfectly. BUT I do NOT understand the reason why. Hope someone can explain it to me.

The reason it's not working as you expect is because your closure is returning another closure.

You can't call de-reference closures, but consider as an example of how it will work:

$k = function() {
    return function() {
        global $y; 
        return $y; 
    }; 
}; 

$first = $k();
print_r($first); // it's a closure, because your main closure returns another closure
$second = $first();
print_r($second); // here is "hello" as you expect

The following will not work:

print_r($k()());

In the case where you use $y when it doesn't exist, the process of returning a closure that uses an undefined variable actually creates a static property on the original closure with a null value, which is why you see this output:

var_dump($u());

object(Closure)#2 (1) {
  ["static"]=>
  array(1) {
    ["y"]=>
    NULL
  }
}

Note that if you do the above with error reporting on you will get an undefined variable error as well.

You appear to be aware already, but I'll mention anyway that $y is not accessible inside the closure because it's outside the function's scope. This is why when you register it using global that it does return what you expect, and also when you use it from the outer closure.

链接地址: http://www.djcxy.com/p/51702.html

上一篇: 在setTimeout中使用JavaScript闭包

下一篇: 使用/ global函数返回匿名函数的PHP函数