|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2006-10-01 19:25 UTC] php_bug dot email at email dot digiways dot com
Description:
------------
if we iterate over $_GET using references (see the example) and pass $_GET to a function, function modifies $_GET and not the local copy.
For example, save the example code in test.php and open
test.php?mykey=foo
.
Reproduce code:
---------------
<?php
function doit($http_get_params)
{
$http_get_params['mykey'] = 'bar';
echo '<br/>'.$_GET['mykey'];
}
foreach($_GET as $key => &$value) {}
echo '<br/>'.$_GET['mykey'];
doit($_GET);
echo '<br/>'.$_GET['mykey'];
?>
Expected result:
----------------
When we open test.php?mykey=foo I expect to see
foo
foo
foo
Actual result:
--------------
When we open test.php?mykey=foo we actually see
foo
bar
bar
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 21:00:01 2025 UTC |
This problem affects all the arrays and not just the $_GET one. Please note that $value is not reused outside of the foreach loop. Effectively this renders foreach by reference useless. Another very simple script which reproduces the problem: $myarray = array( 'mykey' => 'foo' ); function doit($tmp) { $tmp['mykey'] = 'bar'; } foreach($myarray as $key => &$value) {} echo $myarray['mykey']."\n"; doit($myarray); echo $myarray['mykey']."\n"; and outputs foo bar instead of foo fooConfirm with 5.1.6: <?php $a['b']='foo'; function boo($_params){ $_params['b'] = 'bar'; echo $a['b']; } foreach($a as $key => &$val) {} // ?! echo $a['b']; boo($a); echo $a['b']; ?> If you comment out `foreach` loop or remove & near `$val`, code works OK. Loop does nothing and $val is *never* mentioned in code elsewhere.If you add unset($val) after foreach, original array starts back to work as expected: <?php $a['b']='foo'; function boo($_params){ $_params['b'] = 'bar'; echo $_params['b']; } foreach($a as $key => &$val) {} unset($val); echo $a['b']; boo($a); echo $a['b']; /* foo bar foo */ ?>Actually this is not just about foreach, this is the generic problem with references. Apparently if you have a reference to an array element, then when you pass that array to a function and modify that element in the function, then the external array is modified as well, and not just the copy passed to the function. A small example which shows the problem: $myarray = array( 'mykey' => 'foo' ); function doit($tmp) { $tmp['mykey'] = 'bar'; } $value = &$myarray['mykey']; echo $myarray['mykey']."\n"; doit($myarray); echo $myarray['mykey']."\n"; Once again - can anyone point to the documentation page which explains this behaviour ?> And since all the elements in the array are references Are you talking about arrays in general, or about my example? If you are talking about arrays in general, this is simply wrong, a simple example can demostrate that. If you are talking about my example, then please explain why the element in the array becomes a reference if we add a reference to it? I.e. $a = array('foo' => 'bar'); here $a contains the value 'bar' and not the reference to it. $tmp = &$a['foo']; Are you saying that now $a has changed and now it contains a reference to 'bar' and does not contain it as a value any more? Where is this documented?