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

WBOY
Release: 2016-08-04 09:19:49
Original
1309 people have browsed it

The code is as follows:

<code>$a = [1, 2, 3];
foreach($a as $key => &$value) {
    $value = 5;
}
var_dump($a);</code>
Copy after login
Copy after login

The final output result is as follows:

<code>array(3) { [0]=> int(5) [1]=> int(5) [2]=> &int(5) }</code>
Copy after login
Copy after login

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>
Copy after login
Copy after login

The final output result is as follows:

<code>array(3) { [0]=> int(5) [1]=> int(5) [2]=> &int(5) }</code>
Copy after login
Copy after login

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>
Copy after login

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>
Copy after login

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>
Copy after login

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>
Copy after login

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>
Copy after login

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>
Copy after login

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>
Copy after login

$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>
Copy after login

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>
Copy after login

What do you guess the output is?

<code>array(3) {
  [0]=>  int(5)
  [1]=>  int(5)
  [2]=>  &int(6)
}</code>
Copy after login

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>
Copy after login

The output this time looks much more normal:

<code>array(3) {
  [0]=>  int(5)
  [1]=>  int(5)
  [2]=>  &int(5)
}</code>
Copy after login

So, this problem should be a pitfall of PHP global variables.

Related labels:
php
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template