PHP.net关于匿名函数的文档的示例3让我陷入了循环。
第一个 echo 语句打印了$message的值,即使文档让我相信这行不通。
闭包也可以从父作用域继承变量。任何此类变量都必须传递给 use 语言构造。:
// No "use"
$example = function () {
var_dump($message);
};
echo $example();
输出不是失败,而是:
Notice: Undefined variable: message in /example.php on line 6
NULL
string(5) "hello"
在第三个回显语句之前,出现:
$message = 'world';
然后,echo 调用该函数,再次$example以获取 $message 的值。再次string(5) "hello"
输出,而不是string(5) "world"
。由于值$message是在定义$example时定义的,因此 echo 语句仍返回 string(5) "hello"
。我明白了。
接下来,$message"重置"为"hello"。再次调用 Echo,但这次函数$example引用了$message:
$example = function () use (&$message) {
var_dump($message);
};
输出为 string(5) "world"
。我完全不明白这一点。我以为消息的值已重置为你好?
为什么第一个回声仍然有效?为什么第四个打印"世界"?
示例输出
Notice: Undefined variable: message in /example.php on line 6
1: NULL
2: string(5) "hello"
3: string(5) "hello"
4: string(5) "hello"
5: string(5) "world"
6: string(11) "hello world"
第一个回显示例
从示例代码来看,第一个 echo
语句似乎只是导致NULL
,因为此匿名函数不包含use
。(Notice
让您知道$message
未定义。
以下是上下文中的相关代码以供参考:
$message = 'hello';
// No "use"
$example = function () {
var_dump($message);
};
echo $example();
第五个回声示例
虽然 $message
的值已重置为 hello
,但以下代码部分:
// Inherit by-reference
$example = function () use (&$message) {
var_dump($message);
};
echo $example();
表明$message
是通过引用继承的,这意味着当以后使用$message = 'world';
时,我们现在引用(并分配"world"
(与之前相同的$message
变量。
换句话说,当我们定义$example
函数时,我们指向内存中的原始$message
变量(通过&$message
引用(。因此,当我们稍后在代码中调用$example()
时,我们指的是相同的原始$message
变量(我们最近也用$message = 'world';
行进行了更改(。这意味着$example()
将输出我们当前的$message
值(当前设置为 "world"
(,而不是先前设置的值。
以下是上下文中的相关代码以供参考:
// Reset message
$message = 'hello';
// Inherit by-reference
$example = function () use (&$message) {
var_dump($message);
};
echo $example();
// The changed value in the parent scope
// is reflected inside the function call
$message = 'world';
echo $example();
您可能混淆了导致混淆的var_dump
值。让我们分解一下:
最初设置消息
$message = 'hello';
定义函数。使用$message
作为当前值在定义函数时。所以在这里,除非重新定义$example
,否则输出将始终string(5) "hello"
,因为这是定义函数时$message
设置的。
$example = function () use ($message) {
var_dump($message);
};
echo $example(); // Result = string(5) "hello"
即使我们切换$message
的值原始函数在以下情况下使用 $message
的值定义了该函数,因此输出 string(5) "hello"
$message = 'world';
echo $example(); // Result = string(5) "hello"
在继续下一个示例之前将消息重置为"hello">
$message = 'hello';
当使用&$message
定义时,这是说"使用$message
的当前值",而不是在定义函数时保留$message
的值。因此,由于$message
当前设置为 "hello"
,该函数表示这一点。如果我们$message
更改为其他内容并再次运行该函数,它将转储设置$message
值的任何内容。
$example = function () use (&$message) {
var_dump($message);
};
echo $example(); // Result = string(5) "hello"
这表明当函数中的&$message
值在外部更改时,该值会更新。
$message = 'world';
echo $example(); // Result = string(5) "world"