PHP二維數組的引用賦值容易犯的錯誤

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

相關文章
相關標籤/搜索