一,use关键字在闭包中是链接闭包与外部变量的桥梁,也就是说可以把函数外部的变量引入到闭包内部。
二,闭包中使用use声明的变量来自于生成闭包实例时所在作用域内的同名变量,而不是来自于运行闭包时所在作用域内的同名变量。
三,使用引用&和不使用引用就代表了是运行时赋值,还是生成时候赋值,区别在于运行时赋值,会因为引用变量的改变而获取最新的值,申明时赋值是使用时最近的一个变量的值。
四,闭包的函数参数则是和正常的函数参数一样来自于运行时所在作用域内的同名变量
例子如下:
$result = 0;
$one = function () {
//result的作用域在函数内,而函数内并没有定义result变量,所以会有一个警告并返回null
var_dump($result);
};
$two = function () use ($result) {
//闭包中使用use声明的变量来自于生成闭包实例时所在作用域内的同名变量,而不是来自于运行闭包时所在作用域内的同名变量,所以这里输出0
var_dump($result);
};
$three = function () use (&$result) {
//使用引用&后use内的变量会在运行时赋值,会因为引用变量的改变而获取最新的值,所以这里是1
var_dump($result);
};
$four = function ($result) {
//闭包的函数参数则是和正常的函数参数一样来自于运行时所在作用域内的同名变量,所以此处是1
var_dump($result);
};
$result++;
$one(); // null
$two(); // 0
$three(); // 1
$four($result); // 1
die;
$i = 123;
$one = function ($param) use (&$i) {
echo "--- param: $param ---\n";
echo "--- i: $i ---\n";
};
$two = function ($param) use ($i) {
echo "--- param: $param ---\n";
echo "--- i: $i ---\n";
};
$i = 456;
$c = $one('test');
$c1 = $two('test1');
上面两个例子基本相同。
下例:
$i = 123;
function getClosure(&$i)
{
$i = $i.'-'.date('H:i:s');
return function ($param) use (&$i) {
echo "--- param: $param ---\n";
echo "--- i: $i ---\n";
};
}
$c = getClosure($i); //function
$i = 456;
$c('test');
sleep(3);
$c2 = getClosure($i);
$c2('test1');
$c('test2');
注意当getClosure()参数及use参数中有无引用符号(&)的带来的不同效果。
当getClosure()参数及use参数中都有(&)它时表示$i变量都是对同一块内存地址的引用,这也能解释use参数使用引用时的运行时赋值,当use中的参数不带有(&)时是按值传递,即把getClousure中的$i的值传给了use参数,当函数被调用时
return function ($param) use ($i) { 这里虽然$param没被赋值,但是$i有了值,即$i=$i+date('H:i:s');的值。而因为use中
没有使用引用传参,所以use参数的值是在生成闭包函数实例时即第一次调用 $c = getClosure($i); 时$i的值(闭包函数在php中是对象形式,可以自行var_dump())。所以在后面$i=456改变$i的值时不会对其产生影响。只有use参数使用引用传参时才会产生影响。