为什么PHP会将此DOM对象视为数组?

问题描述 投票:1回答:2

我正在学习本教程:

https://www.w3schools.com/php/php_xml_dom.asp

循环使用XML部分是有问题的。 PHP由于某种原因将DOM对象视为数组。此外,var_dump不返回除了length之外的对象属性,但是程序输出看起来像是从哪儿冒出来的。可以以某种方式foreach循环通过对象?如果确实如此,那么这些属性包含在哪里(节点名称和节点值),因为var_dump没有显示它们?

$xml=new DOMDocument ();
$xml->load('note.xml');

$array_of_nodes=$xml->documentElement->childNodes;

var_dump($array_of_nodes);

foreach($array_of_nodes as $item) {
    echo $item->nodeName."  ".$item->nodeValue."<br>";
}

Var转储函数返回:

object(DOMNodeList)#3(1){[“length”] => int(9)} #text

但执行的代码如下所示:

text =

=你

text =

from = Jani

text =

heading =提醒

text =

身体=这周末别忘了我!

text =

php xml domparser php-7.3
2个回答
1
投票

childNodesDOMNodeList类型的财产。 var_dump没有显示任何内容的原因仅仅是因为var_dump只显示了开发人员通过调用这些C函数声明的那些类属性。

ZEND_API int zend_declare_property(...)
ZEND_API int zend_declare_property_null(...)
ZEND_API int zend_declare_property_bool(...)
ZEND_API int zend_declare_property_long(...)
ZEND_API int zend_declare_property_double(...)
ZEND_API int zend_declare_property_string(...)
ZEND_API int zend_declare_property_stringl(...)

资料来源:akond回答:Why doesn't var_dump work with DomDocument objects, while print($dom->saveHTML()) does?

也就是说,DOM扩展的开发人员选择不公开DOMNodeList类的结构。

您可以迭代DOMNodeList的原因是因为它实现了Traversable接口,该接口表示可以使用foreach迭代该类。


0
投票

DOMNodeList实现了几个接口:TraversableArrayAccessCountable。这允许使用通用语法来访问列表中的节点对象。没有它们,您需要使用这样的特定方法和属性:

for ($i = 0; $c = $nodeList->length; $i < $c; $i++) {
  $node = $nodeList->item($i);
  //...
}

Traversable允许您使用foreach

foreach ($nodeList as $node) {
  //...
}

ArrayAccess允许您使用数组语法按索引访问节点,它用->item(...)替换[...]调用。

if (isset($nodeList[0])) {
  $node = $nodeList[0];
  //...
}

Countable允许你使用count($nodeList)而不是$nodeList->length

Traversable具有最大的视觉冲击力。它大大降低了通话的复杂性。但这只是第一个好处。您可以使用typehints或instanceof验证接口。这使您的代码分离,使其更加健壮和可重用。

但是,如果使用Xpath表达式,则通过DOM循环会更容易。如果您之前使用CSS选择器,您可以将Xpath表达式视为更强大的兄弟。

$document = new DOMDocument();
$document->load('note.xml');
$xpath = DOMXpath($document);

foreach($xpath->evaluate('/note') as $item) {
    echo 'To: ', $xpath->evaluate('string(to)', $item), "\n";
    echo 'From: ', $xpath->evaluate('string(from)', $item), "\n";
    echo 'Title: ', $xpath->evaluate('string(heading)', $item), "\n";
    echo 'Text: ', $xpath->evaluate('string(body)', $item), "\n";
}
© www.soinside.com 2019 - 2024. All rights reserved.