为什么 PHP 将此 DOM 对象视为数组?
Why does PHP treats this DOM object like an array?
我正在学习本教程:
遍历 XML 部分是有问题的。
PHP 出于某种原因将 DOM 对象视为数组。此外,var_dump returns 除了长度之外没有任何关于对象属性的信息,但是程序输出看起来像是凭空冒出来的。 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 转储函数returns 这个:
object(DOMNodeList)#3 (1) { ["length"]=> int(9) } #text
但是执行的代码是这样的:
text =
to = Tove
text =
from = Jani
text =
heading = Reminder
text =
body = Don't forget me this weekend!
text =
DOMNodeList
实现了几个接口:Traversable
、ArrayAccess
和 Countable
。这允许使用通用语法来访问列表中的节点对象。没有它们,您将需要使用如下特定方法和属性:
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
视觉冲击力最强。大大降低了调用的复杂度。但这只是第一个好处。您可以使用类型提示或 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";
}
childNodes
是 DOMNodeList
类型的 属性。 var_dump 不显示任何内容的原因很简单,因为 var_dump 只显示那些 class 开发人员通过调用 [=18= 这样的 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
class 的结构。
您可以遍历 DOMNodeList
的原因是因为它实现了 Traversable
接口,该接口表明 class 可以通过使用 foreach
进行遍历。
我正在学习本教程:
遍历 XML 部分是有问题的。 PHP 出于某种原因将 DOM 对象视为数组。此外,var_dump returns 除了长度之外没有任何关于对象属性的信息,但是程序输出看起来像是凭空冒出来的。 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 转储函数returns 这个:
object(DOMNodeList)#3 (1) { ["length"]=> int(9) } #text
但是执行的代码是这样的:
text =
to = Tove
text =
from = Jani
text =
heading = Reminder
text =
body = Don't forget me this weekend!
text =
DOMNodeList
实现了几个接口:Traversable
、ArrayAccess
和 Countable
。这允许使用通用语法来访问列表中的节点对象。没有它们,您将需要使用如下特定方法和属性:
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
视觉冲击力最强。大大降低了调用的复杂度。但这只是第一个好处。您可以使用类型提示或 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";
}
childNodes
是 DOMNodeList
类型的 属性。 var_dump 不显示任何内容的原因很简单,因为 var_dump 只显示那些 class 开发人员通过调用 [=18= 这样的 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
class 的结构。
您可以遍历 DOMNodeList
的原因是因为它实现了 Traversable
接口,该接口表明 class 可以通过使用 foreach
进行遍历。