你們一塊兒來分析一下下面這段代碼: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新手來講,很容易犯這種錯誤而云裏霧裏,不知所措。但願這篇文章能幫到這樣的新手。遍歷