ID: 48646
Comment by: phpwnd at gmail dot com
Reported By: php at mrfoo dot de
Status: Open
Bug Type: SimpleXML related
Operating System: Windows XP / Debian Lenny
PHP Version: 5.2.10
New Comment:
I have investigated this bug a little bit (on 5.2.9), and it seems that
some pointer gets reset to the first node of the list whenever the value
of any node from the list is modified, which makes the next iteration
apply to the second node of the list, where it gets stuck forever. In my
case, modifying a descendant of those nodes (as opposed to the nodes
themselves) did NOT reset the pointer, but I assume it's the same bug.
Here's a reduced test case, which gets stuck on <c>1</c>:
$xml = simplexml_load_string('<root><c>0</c><c>1</c><c>2</c></root>');
$i = -1;
foreach ($xml as $child)
{
if (++$i > 3)
{
die('Too many iterations');
}
echo 'Current node: ', $child->asXML(), "\n\nBefore: ", $xml->asXML(),
"\n";
$xml->c[2] = "changed: $i";
echo 'After: ', $xml->asXML(), "\n\n";
}
Previous Comments:
------------------------------------------------------------------------
[2009-06-22 15:13:21] php at mrfoo dot de
I forget to say: Tested with 5.2.10(win) too.
------------------------------------------------------------------------
[2009-06-22 15:00:26] php at mrfoo dot de
Description:
------------
Tested with: 5.2.6(win), 5.2.9(win) and 5.2.9-0.dotdeb.2 (lin).
Writing a value of a SimpleXML-Element in a foreach loop, causes PHP to
never leave the foreach loop, if you access that element via an extra
index.
Reproduce code:
---------------
error_reporting(E_ALL);
$xmlData = '<root><child><name>A
child</name><info><version>1</version></info></child><child><name>B
child</name><info><version>2</version></info></child><child><name>C
child</name><info><version>2</version></info></child><child><name>D
child</name><info><version>3</version></info></child></root>';
$xml = simplexml_load_string($xmlData);
$i = -1;
foreach ($xml as $xi => $child) {
++$i;
$xml->child[$i]->info->version = rand(1,9);
echo 'I: '.$i.' Xi: '.$xi.' Count : '.count($xml).'
'.$xml->child[$i]->name.' => '.$child->name.'
v:'.$child->info->version."\n";
if($i > 10) {
echo "Too many iterations";
break;
}
}
// Code below works as expected
$xml = simplexml_load_string($xmlData);
for($i = 0, $size = count($xml); $i < $size; ++$i) {
echo 'I: '.$i.' Count : '.count($xml).'
'.$xml->child[$i]->name."\n";
$xml->child[$i]->info->version = rand(1,9);
}
Expected result:
----------------
Something like that:
I: 0 Xi: child Count : 4 A child => A child v:1
I: 1 Xi: child Count : 4 B child => B child v:3
I: 2 Xi: child Count : 4 C child => C child v:3
I: 3 Xi: child Count : 4 D child => D child v:7
I: 0 Count : 4 A child
I: 1 Count : 4 B child
I: 2 Count : 4 C child
I: 3 Count : 4 D child
Actual result:
--------------
I: 1 Xi: child Count : 4 B child => B child v:6
I: 2 Xi: child Count : 4 C child => B child v:6
I: 3 Xi: child Count : 4 D child => B child v:6
I: 4 Xi: child Count : 5 => B child v:6
I: 5 Xi: child Count : 6 => B child v:6
I: 6 Xi: child Count : 7 => B child v:6
I: 7 Xi: child Count : 8 => B child v:6
I: 8 Xi: child Count : 9 => B child v:6
I: 9 Xi: child Count : 10 => B child v:6
I: 10 Xi: child Count : 11 => B child v:6
I: 11 Xi: child Count : 12 => B child v:6
Too many iterations
I: 0 Count : 4 A child
I: 1 Count : 4 B child
I: 2 Count : 4 C child
I: 3 Count : 4 D child
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=48646&edit=1