我在回调函数中遇到了奇怪的行为。下面是在创建替换Map时将字符串的每个字母替换为序列号的代码。
$i = 2;
$map = [];
$token = preg_replace_callback(
'~\w~',
function($matches) use($map, $i) {
$i += 1;
$map[$i] = $matches[0];
print "$i ";
return $i;
},
'$token'
);
print_r($map);
print "\n$token";
奇怪的是它能打印
3 3 3 3 3 Array
(
)
$33333
即$i值被采用,但它正在改变,而不是在下一个回调调用中使用。这是怎么回事如何修复它?
https://onlinephp.io/c/a4b1c0下方的沙盒
2条答案
按热度按时间nfs0ujit1#
通过引用传递
use
参数,如下所示:生产:
您必须澄清您的问题,以确定这是否是除了明显的价值与参考问题之外所期望的。
sulc1iza2#
PHP中的变量捕获默认是 * 仅通过值 * -当创建闭包时,检查
use
列表中每个变量的当前值,并将其分配给闭包中同名的局部变量。在闭包内部赋值给局部变量并不会写回最初捕获的变量,并且每次执行闭包时,捕获的变量都以其最初捕获的值开始。这与其他一些语言不同,如JavaScript,其中闭包携带对其捕获的变量的可写引用。按值捕获通常更容易理解,例如,如果你想在循环中创建一个闭包列表:
如果
$number
是通过引用捕获的,那么所有五个闭包最终都是相同的,都引用同一个变量;因为它是按值捕获的,所以会得到五个不同的闭包,每个闭包都有不同的$number
值。如果你需要引用,你可以在
use
列表中使用&
修饰符:现在,闭包内部的本地名称
$map
与外部的名称$map
引用 * 相同的变量 *-对其中一个的任何修改都将在另一个中可见。这类似于
$myMap = $yourMap
(赋值)和$myMap =& $yourMap
(链接两个变量作为引用)之间的区别。(Note在上述所有情况下,对象的“值”是指向可变对象的指针-因此,如果
$map
是一个对象而不是数组,则调用$map->setSomething(42)
将修改闭包内外可见的同一对象。这与通过引用捕获或赋值不同。)