具有函数内函数的变量的范围?

Daa*_*mer 7 php closures anonymous-function

在Python中,您可以拥有以下内容:

def foo(param1, param2):
    def bar():
        print param1 + param2
    bar()
Run Code Online (Sandbox Code Playgroud)

我在PHP中遇到这种行为有些困难.我希望这可以通过以下方式工作:

function foo($param1, $param2)
{
    function bar()
    {
        echo $param1 + $param2;
    }
    bar();
}
Run Code Online (Sandbox Code Playgroud)

但那失败了.所以我读了一些关于闭包的内容(这被称为闭包不是吗?它是在Python中,我知道).在关于匿名函数的php文档中(他们说它们已被实现为闭包),它们告诉您以下列方式使用use()表达式:

function foo($param1, $param2)
{
    function bar() use($param1, $param2)
    {
        echo $param1 + $param2;
    }
    bar();
}
Run Code Online (Sandbox Code Playgroud)

但那仍然失败.所以我把它改成了PHP-anonymous函数,就像这样:

function foo($param1, $param2)
{
    $bar = function() use($param1, $param2)
    {
        echo $param1 + $param2;
    };
    $bar();
}
Run Code Online (Sandbox Code Playgroud)

这确实有效,但它看起来真的很难看.我错过了什么吗?我可以用任何方式改进吗?或者我只需要使用'丑陋'的方式?

(我不是在寻找关于闭包是否有用的讨论)

bfa*_*tto 4

我在您链接到的手册页上找不到function bar() use($param1, $param2)语法,只有有效的“丑陋”版本(真正的匿名)。我想你必须使用它。

在你的第二个例子中,bar不是一个闭包。要在 PHP 中创建闭包,您必须使用丑陋的useClosure。每个函数都会创建自己的局部作用域,但闭包不是自动的。

PHP 似乎对术语“闭包”有一个奇怪的定义,正如您在阅读手册时可能注意到的那样。他们将其定义为“匿名函数”的同义词:

匿名函数,也称为闭包(...)

令人困惑,对吧?后来,他们解释说,use如果你想继承父作用域,你需要关键字:

闭包还可以从父作用域继承变量。任何此类变量都必须在函数头中声明。

关于闭包的 PHP Wiki rfc 页面为我们提供了一些关于为什么以这种方式实现闭包的提示:

PHP 的作用域概念与其他语言定义的作用域概念有很大不同。将其与变量变量 ($$var) 结合起来,很明显,自动检测闭包内部引用外部作用域中的哪些变量是不可能的。另外,由于默认情况下全局变量在函数内部不可见,因此自动使父作用域可用将打破 PHP 所遵循的当前语言概念。