A problem and solution that should be paid attention to when using references in PHP foreach

Source: Internet
Author: User

I. Problems
Let's take a look at an example:

<? Php
$ Ar = array (1, 2, 3 );
Var_dump ($ ar );
Foreach ($ ar as & $ v ){}
Foreach ($ ar as $ v ){}
Var_dump ($ ar );
?>
Output:

Array (3 ){
[0] =>
Int (1)
[1] =>
Int (2)
[2] =>
Int (3)
}
Array (3 ){
[0] =>
Int (1)
[1] =>
Int (2)
[2] =>
& Int (2)
}
??? Why is the value of the last element of the array changed without assigning values?

I have discovered this problem for a long time. I thought it was a PHP bug at first, and I threw it away. It would be okay if I didn't use references in foreach, use foreach $ k => $ v and then $ ar [$ k] to change the original array, slightly reducing the efficiency.

Ii. Analysis

It took me some time today to read the articles in the reference. I understood a little bit. It turned out to be like this:

When the first foreach with reference is executed, $ v points to the storage space of $ ar [0] at the beginning, and 1 is stored in the space. When foreach ends, $ v points to the storage space of $ ar [2], where 3 is stored. Next we need to start executing the second foreach. Note that, unlike the first foreach, the second foreach does not use a reference. In this case, the value assignment method is used to assign the value of $ ar to $ v in sequence. When the first element is reached, $ ar [0] must be assigned to $ v. The problem is that, since the first foreach is just executed, $ v is not a new variable, but a reference that already exists pointing to $ ar [2]. As a result, when assigning values to $ v, $ ar [0] = 1 is written to the actual storage space of $ ar [2], which is equivalent to assigning values to $ ar [2. The result of the second foreach execution is that the last element of the array is changed to the value of the second to last element. See article 2 for details.

If this is an error, the cause of the error lies in the use of referenced variables. When a referenced variable points to another variable, changing the value of the referenced variable will certainly affect other variables it points. Everyone knows it, but in this foreach example, coincidentally, the same variable is used twice, the previous is the referenced identity, and the last is the normal variable identity, this produces unexpected results. PHP developers also believe that this situation is caused by language characteristics, rather than a bug. Indeed, if you want to fix this problem, one method 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 PHP language features and developers are reluctant to modify them, But Warning is still described in the official documentation.

Iii. Solution

Simple, but not perfect. After using the referenced foreach, unset $ v. The example at the beginning is changed:

<? Php
$ Ar = array (1, 2, 3 );
Var_dump ($ ar );
Foreach ($ ar as & $ v ){}
Unset ($ v );
Foreach ($ ar as $ v ){}
Var_dump ($ ar );
?>
Running 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 before upts the array: https://bugs.php.net/bug.php? Id = 29992
References and foreach: http://schlueters.de/blog/archives/141-References-and-foreach.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.