Home  >  Article  >  Backend Development  >  A problem and solution you need to pay attention to when using references in PHP's foreach_PHP Tutorial

A problem and solution you need to pay attention to when using references in PHP's foreach_PHP Tutorial

WBOY
WBOYOriginal
2016-07-13 10:29:151117browse

1. Questions
Let’s look at an example first:

$ar = array(1, 2, 3);
var_dump($ar);
foreach ($ar as &$v) {}
foreach ( $ar as $v) {}
var_dump($ar);
?>
The output is:

array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
&int(2)
}
? ? ? Why does the value of the last element of the array change without performing an assignment operation?

I discovered this problem a long time ago. I thought it was a bug in PHP at first, so I just ignored it. If you don’t use references in foreach, it will be fine. Use foreach $k => $v and then $ar[$k] To change the original array, there will be a slight loss of efficiency.

2. Analysis

I spent some time today and read the article in Reference. I finally understood it a little bit. It turned out to be like this:

When executing the first foreach using a reference, at the beginning, $v points to the storage space of $ar[0], and 1 is stored in the space. At the end of the foreach, $v points to the storage space of $ar[2]. , 3 is stored in the space. Next, we will start to execute the second foreach. Note that unlike the first foreach, the second foreach does not use references, so it is the assignment method, that is, assigning the value of $ar to $v in sequence. When we get to the first element, $ar[0] is assigned to $v . The problem is here. Since the first foreach has just been executed, $v is not a new variable, but an existing reference pointing to $ar[2]. As a result, when assigning a value to $v, Writing $ar[0] = 1 to the actual storage space of $ar[2] is equivalent to assigning a value to $ar[2]. By analogy, the result of the second foreach execution is that the last element of the array becomes the value of the penultimate element. Refer to article 2 for a detailed schematic.

If this is an error, then the cause of the error lies in the use of reference variables. When a reference variable points to other variables, changing the value of the reference variable will of course affect the other variables it points to. Anyone can understand it individually, but in this foreach example, by coincidence, the same variable is used twice, the first time as a reference and the latter time as an ordinary variable, which produces unexpected effects. PHP developers also believe that this situation is caused by language features and is not a bug. Indeed, if you want to fix this problem, one way is to perform special processing on foreach, and the other is to limit the scope of $v in foreach. Both of these methods are inconsistent with the current language features of PHP, and developers are unwilling to However, it is still explained with Warning in the official documentation.

3. Solution

Simple, but far from perfect, is to unset $v after using the referenced foreach. The starting example is changed to:

$ar = array(1, 2, 3);
var_dump($ar);
foreach ($ar as &$v) {}
unset( $v);
foreach ($ar as $v) {}
var_dump($ar);
?>
Run result:

array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}


Reference

Bug #29992 foreach by reference corrupts the array:https://bugs.php.net/bug.php?id=29992
References and foreach:http://schlueters.de/blog/archives/141 -References-and-foreach.html

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/778129.htmlTechArticle1. Let’s look at an example first: ?php $ar = array(1, 2, 3); var_dump( $ar); foreach ($ar as ? The output is: array(3) { [0]= int(1) [1]= int(2) [2]= int(3) } array(3) { [0 ]= int(1)...
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