我有一段代码看起来像这样:
$app->add(function($req, $res, $next) {
# closure A
$res->on('end', function($res) use ($req) {
# closure B
});
$next();
});
如您所见,我在一个闭包中嵌套了另一个闭包。闭包B从事件中接收$response,因此没有问题。但是它还使用了来自闭包A的$request。
这里,我对'use'变量的作用域有疑问,我看到两种可能性:
1. 任何响应都将具有其自己的请求对象,因为每个传递给$res->on的新侦听器都会重新创建闭包B。因此,有许多闭包B,它们从闭包A的used变量继承了自己的范围。
2. 或者:任何新请求都将替换闭包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
保持了其原始作用域。此外,我注意到对闭包对象进行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专家?