$app->add(function($req,$res,$next) { # closure A $res->on('end',function($res) use ($req) { # closure B }); $next(); });
如你所见,我在一个闭包中有一个闭包.关闭B正在接收来自该事件的$响应,因此它没有问题.但它也使用封闭A的$request.
在这里,我对使用变量的范围有疑问,我看到两种可能性:
>任何响应都有自己的请求对象,因为为每个传递给$res-> on的新侦听器重新创建了闭包B.所以有很多闭包B,它们自己的范围从闭包A的used变量继承一次.
>或者:任何新的请求将替换闭包A中的$req和$res(正常行为……)但也将替换先前创建的闭包B使用的$req.如果请求#1不是,那将会有问题在请求#2到达之前回答(这是基于事件循环的异步代码).
我希望我足够清楚.我问这个是因为,例如,在JavaScript中,我们有时必须使用回调生成器来确保不替换子闭包的范围.
$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保持其原始范围.另外,我注意到Closure对象上var_dump的输出显示了它带来的范围:
object(Closure)#3 (1) { ["static"]=> array(1) { ["res"]=> object(stdClass)#2 (1) { ["val"]=> int(1) } } }
技术说明?我认为那是因为PHP中的闭包是常规PHP对象,其中use是一种构造函数.
>上面示例中的闭包的行为如下:http://pastebin.com/qkQ5GDFw
>但不是这样,我强制PHP保持相同的引用,这是封闭的“构造函数”不可能的:http://pastebin.com/ixfVh2Uf
我对吗?任何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 . "\n"; }; $array = [&$var1,$var2]; $var1 = 3; $var2 = 4; echo $closure(); // echoes 3," . $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){…}).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。