其他闭包中的PHP闭包:范围为;使用「;
我有一个如下代码:其他闭包中的PHP闭包:范围为;使用「;,php,closures,Php,Closures,我有一个如下代码: $app->add(function($req, $res, $next) { # closure A $res->on('end', function($res) use ($req) { # closure B }); $next(); }); 正如你所看到的,我有一个闭包中的闭包。闭包B正在从事件接收$response,因此没有问题。但它也是闭包A中的useing$request。 在这里,我对use'd变量
$app->add(function($req, $res, $next) {
# closure A
$res->on('end', function($res) use ($req) {
# closure B
});
$next();
});
正如你所看到的,我有一个闭包中的闭包。闭包B正在从事件接收$res
ponse,因此没有问题。但它也是闭包A中的use
ing$req
uest。
在这里,我对use
'd变量的范围表示怀疑,我看到了两种可能性:
- 任何响应都将有自己的请求对象,因为闭包B是为传递给
的每个新侦听器重新创建的。所以有很多闭包B,它们自己的作用域从闭包A的使用变量继承一次$res->on
- 或者:任何新请求都将替换闭包A中的
和$req
(正常行为…),但也将替换先前创建的闭包B使用的$res
。如果在请求2到达之前请求1没有得到响应(这是基于事件循环的异步代码),那么这将是有问题的$req
编辑:我尝试了一个理论上做同样事情但更容易测试的代码:
$a = function($var) {
return function() use ($var) {
var_dump($var);
};
};
$fn1 = $a((object) ['val' => 1]);
$fn2 = $a((object) ['val' => 2]);
$fn2();
$fn1();
输出(2,1)表明第一个函数$fn1
保持了其原始范围。另外,我注意到闭包对象上的var\u dump
输出显示了它带来的范围:
object(Closure)#3 (1) {
["static"]=>
array(1) {
["res"]=>
object(stdClass)#2 (1) {
["val"]=>
int(1)
}
}
}
技术解释?我认为这是因为PHP中的闭包是常规PHP对象,use
是一种构造函数
- 上面示例中的闭包的作用如下:
- 但不是这样,我强制PHP保持相同的引用,这在闭包的“构造函数”中是不可能的:
我说得对吗?任何PHP专家?在PHP内部,每个
闭包
对象都包含一个哈希表。此表存储使用use
关键字复制到闭包范围中的值。PHP中的数组也使用哈希表实现
当您在闭包中使用一组变量时,就好像您创建了一个包含所使用的每个变量的数组。每个闭包都包含自己独特的值“数组”,这些值在创建闭包时被初始化。与普通数组不同,闭包中使用的变量表不能修改
$var1 = 1;
$var2 = 2;
$closure = function () use ($var1, $var2) {
return $var1 . ", " . $var2 . "\n";
};
$array = [$var1, $var2];
$var1 = 3;
$var2 = 4;
echo $closure(); // echoes 1, 2
echo $array[0] . ", " . $array[1] . "\n"; // echoes 1, 2
更改$var1
的值不会影响$array[0]
处的值,也不会更改$closure
内$var1
的值
在闭包中使用对象时,该对象可能会在闭包外部更改,这些更改将反映在闭包中。对象在闭包中使用时不会被克隆。但是,由于无法修改变量本身,因此无法将变量更改为指向其他对象
变量也可以通过引用在闭包中使用。这允许在闭包外部修改变量值,并在闭包内部反映这些更改
$var1 = 1;
$var2 = 2;
$closure = function () use (&$var1, $var2) {
return $var1 . ", " . $var2 . "\n";
};
$array = [&$var1, $var2];
$var1 = 3;
$var2 = 4;
echo $closure(); // echoes 3, 2
echo $array[0] . ", " . $array[1] . "\n"; // echoes 3, 2
创建上述闭包时,将在闭包的值表中创建对$var1
的引用,但仅将$var2
的值复制到表中。当$var1
和$var2
的值更改时,闭包中只有$var1
的值更改,因为只有该变量被引用。这同样类似于创建一个数组,其中通过引用将$var1
添加到数组中,但将$var2
的值复制到数组中
在闭包中创建闭包时,内部闭包将在创建闭包时复制变量的值。在另一个闭包中创建它并不重要
$value = 1;
$closure = function ($arg) use ($value) {
return function () use ($arg, $value) {
return $value + $arg;
};
};
$value = 10;
$callback1 = $closure(1);
$callback2 = $closure(2);
echo $callback1() . "\n"; // Echoes 2
echo $callback2() . "\n"; // Echoes 3
TL;DR:创建闭包时,变量的值会复制到闭包中。为了能够修改闭包之外的值,必须通过引用来使用该值(例如,function()use(&$value){…}
)。我不知道为什么我从来没有接受过这个答案,但它在当时对理解PHP的内部结构有很大帮助。谢谢=)