Let's analyze the following code:

<?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;
}

If you think the result of execution of the above code is

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

Or

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

Then you should keep looking down. Because the above two results are wrong, the real implementation results are as follows:

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

Why is it such a result?

Because after the end of the first reference assignment foreach loop, $item2 still refers to the last element of the $arr2 array. The second foreach loop is equivalent to assigning elements of the $arr2 array to $item2 in turn, which is equivalent to assigning values to the last element. That is to say, during the second foreach traversal, the change in the $arr2 array is as follows:

Array when looping to the first element: [1, 2, 1]
Array when looping to the second element: [1, 2, 2]
Array when looping to the third element: [1, 2, 2]

Later

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

The purpose is to tell you that the reference relationship still exists, and that direct assignment can also lead to changes in the data cited. (Actually, the second foreach loop is also a direct assignment, which is a little hard to observe.)

So, how do you get rid of the reference relationship between $item2 and the last element of $arr2? In fact, it's very simple, just add the following statement. That's where the comments are in the source code.

unset($item2);

This can also be said to be a small pit of PHP. For PHP novice, it is easy to make such a mistake and be in a fog. I hope this article can help such a novice.