Home >Backend Development >PHP Tutorial >The problem of using & for key values ​​in foreach loop in php

The problem of using & for key values ​​in foreach loop in php

WBOY
WBOYOriginal
2016-08-04 09:19:491325browse

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?

Reply content:

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.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn