This article is compiled from an article on the stackoverflow website Strange behavior after loop by reference - Is this a PHP bug? —— Using references inside a PHP loop causes very strange behavior - is this a PHP bug? questionWhile I was writing a simple PHP script, something very strange happened. The following is my code. In order to express what I mean clearly, I deliberately removed some unnecessary code:
The output is as follows:
Is this a bug in PHP? Why does such weird behavior happen in PHP? parseAfter the first foreach loop ends, $item still references the last element of the array, which is $arr[2]. Therefore, when starting the second loop, the $item variable will be assigned a new value each time through the loop. In php, if a memory space is referenced, then when you change it, the value of this memory space is directly changed. When $item is changed, the value of $arr[2] is also changed. So, in the second loop: The first time through the loop, the values of $item and $arr[2] become $arr[0], which is 'foo'. In the second loop, the values of $item and $arr[2] become $arr[1], which is 'bar'. In the third loop, the values of $item and $arr[2] become $arr[2], which is 'bar' (the value of $arr[2] is not 'baz', because in the second loop it becomes 'bar').The value of 'baz' is actually lost in the second loop. Translation Note: I don’t like to translate reference into “quote”, of course, let alone “reference”. Every time I explain reference to someone, I tell them: reference is alias. For example, your name is Wu Yichang (haha, nothing unusual), and Ergouzi is your alias. In the spirit of the friendship between good brothers and good friends: “Come on, Ergouzi, I’ll give you these 100 yuan.” You - Wu Yichang - go home with exactly the same pocket, 100 yuan extra. @justjavac debug outputWe can modify the code to debug and trace the execution details of the loop. We can print the value of $item and recursively print the array $arr. When the first loop runs, we can see output like this:
After the loop ends, $item and $arr[2] point to the same memory area. When the second loop runs, we see this output:
In this loop, please note that each time $item is assigned a new value, $arr[2] will also be assigned the same value as $item, because they both still point to the same memory space (Annotation: The original text reads $arr[3], which is suspected to be a typo by the original author @justjavac). When the loop reaches the third value in the array, it contains the value bar because its value was modified during the previous two loops. Still have questionsMaybe you think that I just executed an empty loop foreach ($arr as &$item){} and nothing was done in the loop body. Why did the array elements change? Maybe you think this code should be equivalent to
In fact, that’s not right. The code should be equivalent to:
In other words, In the foreach loop, an assignment operation is implicit. The only difference is that During the assignment process, we used references, so in the first loop, we inadvertently modified the elements inside the array being looped. |