你们一块儿来分析一下下面这段代码:php
<?php $arr = array(); $arr["abc"] = array("sex" => 100, "age" => 18); $arr["bcd"] = array("sex" => 200, "age" => 19); $arr["cde"] = array("sex" => 250, "age" => 17); $arr2 = array(); foreach ($arr as $name => $item) { $item2 = &$arr2[$name]; $item2["sex"] = $item["sex"] + 300; $item2["age"] = $item["age"] + 2; } //unset($item2); foreach ($arr2 as $name => $item2) { echo "name: $name, age: " . $item2['age'] . ", sex: " . $item2['sex'] . PHP_EOL; } echo "too little".PHP_EOL; //unset($item2); $item2 = array("age" => 30, "sex" => 1000); print_r($item2); echo "next step".PHP_EOL; foreach ($arr2 as $name => $item) { echo "name: $name, age: " . $item['age'] . ", sex: " . $item['sex'] . PHP_EOL; }
若是你以为上面的代码的执行结果是数组
name: abc, age: 20, sex: 400 name: bcd, age: 21, sex: 500 name: cde, age: 19, sex: 550 too little Array ( [age] => 30 [sex] => 1000 ) next step name: abc, age: 20, sex: 400 name: bcd, age: 21, sex: 500 name: cde, age: 19, sex: 550
或者是spa
name: abc, age: 20, sex: 400 name: bcd, age: 21, sex: 500 name: cde, age: 21, sex: 500 too little Array ( [age] => 30 [sex] => 1000 ) next step name: abc, age: 20, sex: 400 name: bcd, age: 21, sex: 500 name: cde, age: 21, sex: 500
那么你就应该继续往下看了。由于上面两个结果都是错误的,真正的执行结果以下:code
name: abc, age: 20, sex: 400 name: bcd, age: 21, sex: 500 name: cde, age: 21, sex: 500 too little Array ( [age] => 30 [sex] => 1000 ) next step name: abc, age: 20, sex: 400 name: bcd, age: 21, sex: 500 name: cde, age: 30, sex: 1000
为何会是这样一个结果呢?blog
由于在第一个引用赋值的foreach循环结束之后,$item2依然引用着$arr2数组的最后一个元素。而第二个foreach循环的时候,至关于把$arr2数组的元素依次赋值给$item2,也就至关于赋值给最后一个元素。也就是说,在第二个foreach遍历的过程当中,$arr2数组的变化是这样的:it
循环到第1个元素时的数组:[1, 2, 1] 循环到第2个元素时的数组:[1, 2, 2] 循环到第3个元素时的数组:[1, 2, 2]
然后的class
$item2 = array("age" => 30, "sex" => 1000);
是为了告诉你们引用关系依然存在,而且,直接赋值也会致使引用的数据发生变化。(其实,第二个foreach循环时也是使用的直接赋值,只是有点很差观察出来)foreach
那么,怎样才能将$item2与$arr2的最后一个元素的引用关系去掉呢?其实很简单,只要添加如下语句就能够了。也就是源代码中注释的地方。循环
unset($item2);
这也能够说是PHP的一个小坑,对于PHP新手来讲,很容易犯这种错误而云里雾里,不知所措。但愿这篇文章能帮到这样的新手。遍历