php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74751 Array content changes but doesn't change
Submitted: 2017-06-13 03:23 UTC Modified: 2017-06-13 03:35 UTC
From: grmnpl46 at gmail dot com Assigned:
Status: Not a bug Package: Arrays related
PHP Version: Irrelevant OS: any
Private report: No CVE-ID: None
 [2017-06-13 03:23 UTC] grmnpl46 at gmail dot com
Description:
------------
I'm altering only the first element of the array but the second one is somehow modified too - or the first one is displayed instead. This doesn't happen if at the second foreach I put also reference.

Test script:
---------------
$arr = [
	[1, 2],
	[3, 4]
];

foreach($arr as $i => &$a)
{
	if($i === 0)
	{
		$a[0] = 6;
		$a[1] = 7;
	}
}

//correct result
print_r($arr);

foreach($arr as &$a)
	print_r($a); //correct result
foreach($arr as $a)
	print_r($a); //bug - displays same values twice


Expected result:
----------------
the 2 arrays should have different values.

Actual result:
--------------
the 2 arrays are identical

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-06-13 03:35 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2017-06-13 03:35 UTC] requinix@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

Please read the red warning on the foreach docs page.
 [2017-06-14 16:05 UTC] danack@php.net
grmnpl - the explanation is that $a is still a variable which is a reference to the original array. Writing values into it, will write that value into the original array.


Re-using the names of variables is usually a bad idea - particularly when using them with references.

The behaviour you probably expected can be achieved by explicitly unsetting the $a variable:


<?php

$arr = [
	[1, 2],
	[3, 4]
];

foreach($arr as $i => &$a)
{
	if($i === 0)
	{
		$a[0] = 6;
		$a[1] = 7;
	}
}

//correct result
print_r($arr);

foreach($arr as &$a)
	print_r($a); //correct result

unset($a);

foreach($arr as $a)
	print_r($a); //bug - displays same values twice

?>



This example shows that writing any variable into $a will alter the original array.

<?php

$arr = [
	[1, 2],
	[3, 4]
];

foreach($arr as $i => &$a) {
	if($i === 0) {
		$a[0] = 6;
		$a[1] = 7;
	}
}

$a = "Wooo, magic";

foreach($arr as $b) {
    print_r($b); 
}

?>
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Dec 14 05:01:23 2019 UTC