今天看到了一个很神奇的代码:
写出如下程序的输出结果:
<?php
$data = ['a','b','c'];
foreach($data as $key=>$val){
$val = &$data[$key];
print_r($data);
}
问:最终$data的值是多少?
一开始以为$data变量的值是不会变的,因为咋看上去并没有赋值操作。
但是运行了一次之后就发现不同了
Array
(
[0] => a
[1] => b
[2] => c
)
Array
(
[0] => b
[1] => b
[2] => c
)
Array
(
[0] => b
[1] => c
[2] => c
)
特地去翻了一下官方文档,原来在php的foreach还有特殊说明的:
什么意思呢?就是说实际运行的代码是这样的:
$data = ['a', 'b', 'c'];
//1、
foreach ($data as $key => $val) {
$val = &$data[$key]; // 进行引用传值,此时的$val内存地址被赋值为$data[0]
print_r($data);
}
//2、此时的$val内存地址为$data[0],foreach将$data[1]赋值给$val,所以$data[1]被赋值到了$data[0]
foreach ($data as $key => $val) { // $data =['b','b','c']
$val = &$data[$key]; // 进行引用传值,此时的$val内存地址被赋值为$data[1]
print_r($data);
}
//2、此时的$val内存地址为$data[1],foreach将$data[2]赋值给$val,所以$data[2]被赋值到了$data[1]
foreach ($data as $key => $val) { // $data =['b','c','c']
$val = &$data[$key]; // 进行引用传值,此时的$val内存地址被赋值为$data[2]
print_r($data);
}
在第一次循环的时候,$val就被定义成了指向$data['0']的一个引用变量,而foreach的特殊机制在下次循环的时候保留了这个变量与内存地址,所以就把$data[0]和$data[1]覆盖了
只要在每次循环结束前,加上一个unset()就可以把这个引用变量给清除了ヽ(≧□≦)ノ