php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70387 Array corruption after iteration with a &pointer
Submitted: 2015-08-29 11:39 UTC Modified: 2015-08-30 23:45 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: oleg dot nucer at gmail dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.6.12 OS: Windows 8.1 x64
Private report: No CVE-ID: None
 [2015-08-29 11:39 UTC] oleg dot nucer at gmail dot com
Description:
------------
I've found a realy strange bug .. Just look to the script and to the output! I've killed a half of our to understand what's going on in my script...

After iterating over array with a pointer variable the array becomes corrupted for next time iteration...

Look at the last element in foreach loop, it's the same with previous!!

Test script:
---------------
<?
	$sample = [
		[ "first", 1 ],
		[ "second", 2 ],
		[ "third", 3 ]
	];
	
	foreach ( $sample AS &$s )
	{
	}
	
	echo "Array: <pre>".print_r( $sample, 1 )."</pre><br/>";
	
	foreach ( $sample AS $s )
	{
		echo "Element: <pre>".print_r( $s, 1 )."</pre>";
	}
?>

Expected result:
----------------
Array:
Array
(
    [0] => Array
        (
            [0] => first
            [1] => 1
        )

    [1] => Array
        (
            [0] => second
            [1] => 2
        )

    [2] => Array
        (
            [0] => third
            [1] => 3
        )

)

Element:
Array
(
    [0] => first
    [1] => 1
)
Element:
Array
(
    [0] => second
    [1] => 2
)
Element:
Array
(
    [0] => third
    [1] => 3
)

Actual result:
--------------
Array:
Array
(
    [0] => Array
        (
            [0] => first
            [1] => 1
        )

    [1] => Array
        (
            [0] => second
            [1] => 2
        )

    [2] => Array
        (
            [0] => third
            [1] => 3
        )

)

Element:
Array
(
    [0] => first
    [1] => 1
)
Element:
Array
(
    [0] => second
    [1] => 2
)
Element:
Array
(
    [0] => second
    [1] => 2
)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-08-30 23:24 UTC] mark at lange dot demon dot co dot uk
This is documented behaviour with an explanation on the [foreach PHP docs page](http://php.net/manual/en/control-structures.foreach.php) and a description of how to avoid it

 > Warning
 > Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().
 [2015-08-30 23:45 UTC] rasmus@php.net
-Status: Open +Status: Not a bug
 [2015-08-30 23:45 UTC] rasmus@php.net
And this is not a bug. Think about what the code would look like if you unrolled your loops and manually assigned each element to $s by reference and then started using $s as a non-reference suddenly. Obviously the last thing $s is referencing will now be modified by that assignment unless you clear it.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Fri Oct 30 20:01:24 2020 UTC