<?php
$arr = [1,2,3];
foreach ($arr as &$a){
$a = $a * $a;
print_r($a);
print_r("\n");
print_r($arr);
}
print_r($a);
print_r("\n");
foreach($arr as $a){
print_r($a);
print_r("\n");
print_r($arr);
}
输出结果是
1
Array
(
[0] => 1
[1] => 2
[2] => 3
)
4
Array
(
[0] => 1
[1] => 4
[2] => 3
)
9
Array
(
[0] => 1
[1] => 4
[2] => 9
)
9
————————————————分界线————————————————————
1
Array
(
[0] => 1
[1] => 4
[2] => 1
)
4
Array
(
[0] => 1
[1] => 4
[2] => 4
)
4
Array
(
[0] => 1
[1] => 4
[2] => 4
)
这个过程很清晰了,在第一次循环后,$a作为引用,最后一次循环时,是直接把$arr元素的最后一个地址赋值给了$a,所以$a是一个引用,且指向最后$arr的最后一个地址,从分界线以前就能发现$a输出的是9。
紧接着第二次循环,大家要记得这是$a仍然是个引用,且指向$arr的最后一个元素9,第二次的foreach中的$a并不像普通的变量一样,重新分配内存,如果是普通变量则会创建值,将$a指向这个新值,但是引用的特点是将新值替换掉原来的值
这样讲解就清晰明了了。
解决这个问题的方式,则是及时的将引用释放掉unset($a),与下面的$a变量不混淆,只要及时的unset($a),再次出现$a时,php会自动地将$a设置为一个普通变量,并分配它自己的地址和值空间,每次foreach都是提取数据往$a的值中拷贝
从编码性能来看,使用&会造成一些开发思考上的负担,但是这个过程少了拷贝值的过程,如果在密集计算和大数据量下,引用的优势就变得很明显了