$xmlString = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<text>
<mod id = "id 0" name="name a">
<item id="id 1"/>
<item id="id 2"/>
</mod>
<mod id = "id 3" name = "name b">
<item id="id 4"/>
<item id="id 5"/>
</mod>
<mod id = "id 6" name="name c">
<item id="id 7"/>
<item id="id 8"/>
</mod>
</text>
XML;
// function to apply the 'fn' to all the elements
// question1: do I really need to write such a function? I did search but failed to find one, does PHP already have one?
function for_each(Traversable $it, $fn) {
foreach($it as $item) {
if(call_user_func_array($fn, array($item)) === false) {
break;
}
}
}
$it = new SimpleXMLIterator($xmlString);
function callback($a) {
$a['id'] = 'xxxxxxx'; // just modify every 'id' to 'xxxxxxx'
}
for_each(new RecursiveIteratorIterator($it, 1), 'callback');
// question 2: after the loop, only three 'id' are modified, why ?
var_dump($it->asXML());
First, may I ask which version of PHP you’re using? I can only reproduce your described behaviour (only 3 ids changed) on versions 5.2.4 and below. PHP 5.2.5 included a couple of changes to the RecursiveIteratorIterator which fix your issue so, using that version or newer, the code will do what you want it to do.
As for your for_each() function, there is a built-in function which does similar to what you want (but not the same!): iterator_apply(). You would use it like:
Thanks you, the iterator_apply is exactly what I want, it is much multipurpose than the for_each().
after I upgrade PHP from 5.2.0 to 5.2.14, all the ‘id’ are modified to ‘xxxxxx’, it seems to be a bug of previous PHP ?