The code is as follows:
<code>$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = 5; } var_dump($a);</code>
The final output result is as follows:
<code>array(3) { [0]=> int(5) [1]=> int(5) [2]=> &int(5) }</code>
Question: Why does the address character appear before the last key value?
The code is as follows:
<code>$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = 5; } var_dump($a);</code>
The final output result is as follows:
<code>array(3) { [0]=> int(5) [1]=> int(5) [2]=> &int(5) }</code>
Question: Why does the address character appear before the last key value?
The & appearing in this var_dump means that you can use another variable to change its value.
Like you
<code class="php">$b = &$a[0]; var_dump($a);</code>
When printing here, an & symbol will appear in the first key value, indicating that you can use other variables ($b) to change its value.
Let’s first understand the basic usage of &
.
<code class="php">$b = $c = 1; $a = &$b; $a = 2; echo "b=$b,c=$c\n"; $a = &$c; $a = 100; $a = 200; echo "b=$b,c=$c\n"; unset($a); $a = 500; echo "b=$b,c=$c\n";</code>
After $a is specified as a reference to $b above, unless it is specified again as another reference or unset($a), changing $a will change the value of the corresponding $b.
The same is true for your foreach. If you break the loop into single steps, it will look like this:
<code class="php">$value = &$a[0]; $value = 5; $value = &$a[1]; $value = 5; $value = &$a[2]; $value = 5;</code>
When the loop runs to the end, $value is a reference to $a[2], so it is equivalent to this form:
<code class="php">$a[0] = 5; $a[1] = 5; $value = &$a[2]; $a[2] = 5; var_dump($a);</code>
It is not difficult to understand why var_dump prints an & symbol on the last key-value pair.
Under normal circumstances, this will not cause any big problems, but due to the scope problem of foreach, $value can still be used after the loop exits, so some incredible bugs will appear.
Like this
<code class="php">$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = $value+5; } var_dump($a); // [6,7,8] foreach($a as $value){} var_dump($a); // [6,7,7]</code>
After adding an empty foreach, $a becomes unreasonable. This bug is incredible. The reason is also because the $value in the empty foreach is a reference to the top &a[2].
The empty foreach is equivalent to this:
<code class="php">$value = &$a[2]; $value = $a[0]; $value = $a[1]; $value = $a[2];</code>
Did you notice that since $value is a reference to $a[2], the above can be rewritten like this:
<code class="php">$a[2] = $a[0]; $a[2] = $a[1]; $a[2] = $a[2];</code>
$a[2] is constantly changing in the empty foreach, and since $a[2] has become the value of $a[1], $a[2] = $a[2]; has no effect. , the value is still $a[1];
This incredible bug is caused by the scope of the variable $value, so either change the name or unset $value first.
<code class="php">$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = $value+5; } var_dump($a); // 要么unset unset($value); // 要么foreach里不要用上面同名的$value,改为$value2222 foreach($a as $value2222){} var_dump($a);</code>
First of all, I want to say that this is a very, verygood question. I believe the questioner is not unable to distinguish between quotes and non-quotes.
I did two tests first:
<code>$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = 5; } foreach($a as $key => $value) { $value = 6; } var_dump($a);</code>
What do you guess the output is?
<code>array(3) { [0]=> int(5) [1]=> int(5) [2]=> &int(6) }</code>
Another test is:
<code>$a = [1, 2, 3]; foreach($a as $key => &$value) { $value = 5; } foreach($a as $key => $value2) { $value2 = 6; } var_dump($a);</code>
The output this time looks much more normal:
<code>array(3) { [0]=> int(5) [1]=> int(5) [2]=> &int(5) }</code>
So, this problem should be a pitfall of PHP global variables.