php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52369 trying to delete nodes while looping domnodelist do not delete them
Submitted: 2010-07-18 13:14 UTC Modified: 2013-12-03 08:18 UTC
Votes:3
Avg. Score:4.3 ± 0.9
Reproduced:3 of 3 (100.0%)
Same Version:2 (66.7%)
Same OS:0 (0.0%)
From: giorgio dot liscio at email dot it Assigned:
Status: Not a bug Package: DOM XML related
PHP Version: 5.3.2 OS: all
Private report: No CVE-ID: None
 [2010-07-18 13:14 UTC] giorgio dot liscio at email dot it
Description:
------------
hi, as summary says
here is the test code

<?php

	$s = '<div><abc /><abc /><abc /><abc /></div>';
	$a = new DOMDocument(); $a->loadXML($s);
        $els = $a->getElementsByTagName("abc");


	// uncomment those three lines to fix
	//foreach($els as $b)
	//	$els2[]=$b;	
	//$els=$els2;

	
	foreach($els as $el)
		$el->parentNode->removeChild($el);

	echo "<textarea rows=20 cols=50>";
	echo "document element (<div>) should be empty:\n";
	echo $a->saveXML();
	
	?>

uncomment lines to see the expected behavior


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-07-20 01:11 UTC] giorgio dot liscio at email dot it
not a bug?
 [2012-07-29 20:08 UTC] gmblar+php at gmail dot com
Create a document

<?php

$document = new DOMDocument();
$document->formatOutput = true;
$root = $document->appendChild($document->createElement('root'));
for($i = 0; $i < 10; $i++) {
    $root->appendChild($document->createElement('child', $i));
}
echo $document->saveXML();

?>

Result:
<?xml version="1.0"?>
<root>
  <child>0</child>
  <child>1</child>
  <child>2</child>
  <child>3</child>
  <child>4</child>
  <child>5</child>
  <child>6</child>
  <child>7</child>
  <child>8</child>
  <child>9</child>
</root>


When you alter elements in the DOMNodeList in a foreach loop, it may produce 
unexpected results
<?php

foreach($document->getElementsByTagName('child') as $element) {
    $root->removeChild($element);
}
echo $document->saveXML();

?>

Result:
<?xml version="1.0"?>
<root>
  <child>1</child>
  <child>3</child>
  <child>5</child>
  <child>7</child>
  <child>9</child>
</root>


First copy the elements from the DOMNodeList to an array with iterator_to_array
<?php

foreach(iterator_to_array($document->getElementsByTagName('child')) as $element) {
    $root->removeChild($element);
}

?>

Result:
<?xml version="1.0"?>
<root/>
 [2013-12-03 08:18 UTC] mike@php.net
-Status: Open +Status: Not a bug
 [2013-12-03 08:18 UTC] mike@php.net
Yes, usually manipulating the set of an active iterator produces undefined results.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Tue Nov 24 21:01:23 2020 UTC