What exactly does PHP's SimpleXMLElement :: children() return?
According to the manual:
Returns a SimpleXMLElement element, whether the node has children or not.
But first of all, this doesn't make sense to me. children() should surely return an array of SimpleXMLElements. If the node has more than one child, how can returning a single SimpleXMLElement possibly represent that?
Second of all, that doesn't tie in with the example that follows in the manual:
foreach ($xml->children() as $second_gen)
echo ' The person begot a ' . $second_gen['role'];
How can you foreach through a SimpleXMLElement? I thought you could only do that with arrays? Also, what the heck's going on with the $second_gen values? So children() returns an array of associative arrays...?
There must be some somewhat deep PHP grammar rules going on here that I'm not aware of so please explain or point me to the relevant manual pages.
Why not try for yourself (demo):
$foo = new SimpleXmlElement(
'<foo>
<bar>
<baz id="b1"/>
<baz id="b2"/>
<baz id="b3"/>
</bar>
</foo>
');
Then do
var_dump($foo->bar->baz[0]->children());
Output
object(SimpleXMLElement)#4 (0) {}
Then do
var_dump($foo->bar->children());
Output
object(SimpleXMLElement)#2 (1) {
["baz"]=>
array(3) {
[0]=>
object(SimpleXMLElement)#3 (0) {
}
[1]=>
object(SimpleXMLElement)#5 (0) {
}
[2]=>
object(SimpleXMLElement)#6 (0) {
}
}
}
How can you foreach through a SimpleXMLElement? I thought you could only do that with arrays?
Well, that's wrong. You can foreach any Traversable (e.g. objects and arrays, etc) and any object implementing the Iterator interface. Here is the class signature of SimpleXmlElement
Class [ <internal:SimpleXML> <iterateable> class SimpleXMLElement implements Traversable ] {
Also, what the heck's going on with the $second_gen values? So children() returns an array of associative arrays...?
No, it doesnt. It returns a SimpleXmlElement
. Accessing a SimpleXmlElement
by Array Access fetches attributes from the current node (or accesses a child node by position if numeric), e.g.
echo $foo->bar->baz[2]['id']; // prints "b3"
This is somewhat non-obvious because the SimpleXmlElement
doesnt implement ArrayAccess
but it's how it is implemented in C. See http://www.php.net/manual/en/simplexml.examples-basic.php for more examples.
From the manual
Note: SimpleXML has made a rule of adding iterative properties to most methods. They cannot be viewed using var_dump() or anything else which can examine objects.
This just means that the object that is returned can be iterated. So even though you're given a single object you can iterate through it.
Just look at the class definition : http://www.php.net/manual/en/class.simplexmlelement.php (notice that it implements traversable)
Since each object you traverse is in itself an SimpleXML object, you can simply call children()
on it to go one level deeper.
精彩评论