Home >Backend Development >PHP Tutorial >Why Does the Last Element Duplicate in PHP's Foreach Loop with Pass-by-Reference?
PHP Foreach Pass by Reference Enigma: Mysterious Last Element Duplication
In PHP, when you employ the foreach loop with a pass-by-reference assignment (e.g., foreach ($arr as &$item)), unexpected behavior can arise. Consider this perplexing example:
$arr = ["foo", "bar", "baz"]; foreach ($arr as &$item) { /* do nothing by reference */ } print_r($arr); foreach ($arr as $item) { /* do nothing by value */ } print_r($arr); // $arr has inexplicably changed
This code outputs:
Array ( [0] => foo [1] => bar [2] => baz ) Array ( [0] => foo [1] => bar [2] => bar )
Explaining the Duplication
After the first foreach loop, each element of $arr is still referenced by $item. When the second loop iterates, it replaces the value of each element with the value of $item, which happens to be the last element of the array. This means that each element of $arr is set to the value of $arr[2], leading to the duplication of the last element in the output.
Debugging the Output
To illustrate this behavior, let's debug the output by adding print statements to each foreach iteration:
foreach ($arr as &$item) { echo "Item: $item<br>"; print_r($arr); echo "<br>"; } foreach ($arr as $item) { echo "Item: $item<br>"; print_r($arr); echo "<br>"; }
This outputs:
Item: foo Array ( [0] => foo [1] => bar [2] => baz ) Item: bar Array ( [0] => foo [1] => bar [2] => baz ) Item: baz Array ( [0] => foo [1] => bar [2] => baz ) Item: foo Array ( [0] => foo [1] => bar [2] => foo ) Item: bar Array ( [0] => foo [1] => bar [2] => bar ) Item: bar Array ( [0] => foo [1] => bar [2] => bar )
You can clearly see that each element of $arr is set to the value of $item, which changes to the last element of the array during the second foreach loop.
Bug or Intended Behavior?
This behavior is not a bug. It is a consequence of passing by reference. The foreach loop simply assigns the value of the current element to the variable specified in the loop header. In this case, by referencing $item, we are modifying the original array elements in the second loop. This is equivalent to the following code:
for ($i = 0; $i < count($arr); $i++) { $arr[$i] = $item; }
Therefore, the observed behavior is not a bug but a result of the intended semantics of pass-by-reference in PHP. To avoid such behavior, use pass-by-value in the second foreach loop by simply assigning the value of each element to $item: foreach ($arr as $item).
The above is the detailed content of Why Does the Last Element Duplicate in PHP's Foreach Loop with Pass-by-Reference?. For more information, please follow other related articles on the PHP Chinese website!