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

或者是

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

那么你就應該繼續往下看了。因為上面兩個結果都是錯誤的,真正的執行結果如下:

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

為什么會是這樣一個結果呢?

因為在第一個引用賦值的foreach循環結束以后,$item2依然引用着$arr2數組的最后一個元素。而第二個foreach循環的時候,相當於把$arr2數組的元素依次賦值給$item2,也就相當於賦值給最后一個元素。也就是說,在第二個foreach遍歷的過程中,$arr2數組的變化是這樣的:

循環到第1個元素時的數組:[1, 2, 1]
循環到第2個元素時的數組:[1, 2, 2]
循環到第3個元素時的數組:[1, 2, 2]

而后的

$item2 = array("age" => 30, "sex" => 1000);

是為了告訴大家引用關系依然存在,並且,直接賦值也會導致引用的數據發生變化。(其實,第二個foreach循環時也是使用的直接賦值,只是有點不好觀察出來)

那么,怎樣才能將$item2與$arr2的最后一個元素的引用關系去掉呢?其實很簡單,只要添加以下語句就可以了。也就是源代碼中注釋的地方。

unset($item2);

這也可以說是PHP的一個小坑,對於PHP新手來說,很容易犯這種錯誤而雲里霧里,不知所措。希望這篇文章能幫到這樣的新手。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM