【问题标题】:PHP function returning anonymous function with use / globalPHP函数返回匿名函数使用/全局
【发布时间】:2015-12-07 12:04:53
【问题描述】:

我是 PHP 新手,目前正在学习闭包的概念。

对于使用 use() 的关闭,我知道我可以执行以下操作:

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

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

但是,我在执行返回另一个匿名函数的函数时遇到问题,例如:

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

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

我知道当我将上面的代码修改为下面的代码时,代码可以完美运行。但我不明白为什么。

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

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

以类似的方式,我对以下使用全局的代码有疑问,为什么它不起作用:

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

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

请不要告诉我如何交换代码以使其工作。正如我所尝试的那样,我知道如何更改这些代码并使其正常工作。相反,我想知道为什么 global 和 use() 在我调用它们以返回另一个匿名函数时不起作用。

【问题讨论】:

    标签: php closures anonymous-function


    【解决方案1】:

    我知道当我将上面的代码修改为下面的代码时,代码可以完美运行。但我不明白为什么。希望有人能给我解释一下。

    它没有按预期工作的原因是因为您的闭包正在返回另一个闭包。

    您不能调用取消引用闭包,但可以作为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
    

    以下将不起作用:

    print_r($k()());
    

    在您use $y 不存在的情况下,返回使用未定义变量的闭包的过程实际上会在原始闭包上创建一个具有空值的静态属性,这就是您看到此输出的原因:

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

    注意,如果您使用error reporting on 执行上述操作,您也会收到未定义变量错误。

    您似乎已经意识到了,但我还是要提一下 $y 在闭包内是不可访问的,因为它超出了函数的范围。这就是为什么当您使用global 注册它时它确实返回了您所期望的,并且当您从外部闭包中use 它时也是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-29
      • 1970-01-01
      • 1970-01-01
      • 2016-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多