Skip to content

Instantly share code, notes, and snippets.

@xurizaemon
Created February 1, 2012 00:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xurizaemon/1714131 to your computer and use it in GitHub Desktop.
Save xurizaemon/1714131 to your computer and use it in GitHub Desktop.
Unexpected behaviour when running foreach across an array of objects in PHP
<pre>
<?php
/*
after using foreach to iterate /by reference/ across an array containing objects,
then on the second foreach of the same array,
the final member of the array gets overwritten by the previous
and c=b
if we don't iterate by reference on the first pass, then it doesn't happen
and c=c at the end
is this right?
*/
$array = array(
'a' => new stdClass(),
'b' => new stdClass(),
'c' => new stdClass(),
);
$array['a']->name = 'a';
$array['b']->name = 'b';
$array['c']->name = 'c';
// by reference
foreach ($array as $k => &$value) {
print($k . ' is '. $value->name . "\n");
}
// no reference this time, but last member gets clobbered
foreach ($array as $k => $value) {
print($k . ' is '. $value->name . "\n");
}
/*
a is a
b is b
c is c
a is a
b is b
c is b <---------------------
*/
// ok, let's try that again
// reset the array
$array = array(
'a' => new stdClass(),
'b' => new stdClass(),
'c' => new stdClass(),
);
// some properties
$array['a']->name = 'a';
$array['b']->name = 'b';
$array['c']->name = 'c';
// no reference
foreach ($array as $k => $value) {
print($k . ' is '. $value->name . "\n");
}
// again, no reference; last member is OK
foreach ($array as $k => $value) {
print($k . ' is '. $value->name . "\n");
}
/*
a is a
b is b
c is c
a is a
b is b
c is c <---------------------
*/
@xurizaemon
Copy link
Author

https://bugs.php.net/bug.php?id=49386 is an earlier bug report re the same behaviour. At http://php.net/manual/en/control-structures.foreach.php docs say,

  • Warning: Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().

This is still fucked up behaviour.

@thsutton
Copy link

thsutton commented Feb 1, 2012

Yeah, PHP has crappy variable scoping. OTOH, they'd probably make lexical scoping suck too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment