Simple XML如何使用[]运算符?

时间:2009-03-19 21:54:44

标签: php arrays operators simplexml

在PHP中,您可以在元素上使用方括号来访问属性:

$node = /* SimpleXMLElement */
$id = $node['id'];

奇怪的是$id不是字符串,而是另一个SimpleXMLElement。为什么不是一个字符串?我发现自己在这个地方使用了strval()

方括号如何工作?我可以用自己的课程吗?我没有在文档中看到任何关于此事的内容。

4 个答案:

答案 0 :(得分:3)

您可以通过实现ArrayAccess interface来提供对象的访问,这是PHP标准库的一部分。这个界面就是其中之一“即使你没有安装完整的PHP标准库扩展,你仍然可以在PHP 5中使用这个界面”。

通过实现此接口,并为您的类定义四种方法

public boolean offsetExists  ( string $offset  )
public mixed offsetGet ( string $offset )
public void offsetSet ( string $offset , string $value )
public void offsetUnset ( string $offset )

您应该能够在实例化对象中使用方括号。

对于SimpleXML本身,我不确定它是否实际实现了ArrayAccess接口,或者是否在PHP源代码的幕后发生了其他事情,从而赋予它超强的功能。

答案 1 :(得分:1)

我相信你可以扩展SimpleXML类,并在其中实现ArrayAccess。

答案 2 :(得分:1)

对于SimpleXML本身,它是一个内部类。它为PHP用户空间实现的唯一接口是Traversable

在内部使用方括号访问时,SimpleXML会根据索引/键的值和类型查找内容。

如果类型为整数(long),则尝试查找零索引编号元素并提供其值。如果根元素有$root这样的具体节点元素,$root[0]将表示该元素的值:

$root = new SimpleXMLElement('<root a="vala"></root>');
$root[0] = 'hello'; 
# <root a="vala">hello</root>
#                ^^^^^- changed value                     

根元素有点无趣,因为只存在一个。拥有父母的元素更有趣。

$root = new SimpleXMLElement('<root a="vala"><child /></root>');
$root->child[0] = 'hello'; 
# <root a="vala"><child>hello</child></root>
#                       ^^^^^- changed value

设置第一个child元素的节点值。索引up-one将添加一个新子项:

$root = new SimpleXMLElement('<root a="vala"><child /></root>');
$root->child[1] = 'hello'; 
# <root a="vala"><child/><child>hello</child></root>
#                        ^--  added child --^

这与数组非常相似。整数的字符串,就像一个整数:

$root->child['1'] = 'hello'; 
# <root a="vala"><child/><child>hello</child></root>
#                        ^--  added child --^

将括号留空,将在末尾添加一个新元素:

$root->child[] = 'hello';
$root->child[] = 'world';
# <root a="vala"><child/><child>hello</child><child>world</child></root>

到目前为止整数和“没有”偏移。与标准PHP数组一样,不得将其与传递NULL混淆。它将被转换为空字符串""

使用任何字符串,SimpleXML将查找属性节点而不是子元素节点:

$root = new SimpleXMLElement('<root a="vala"></root>');
echo $root['a'], "\n"; # vala

这也适用于添加属性:

$root = new SimpleXMLElement('<root a="vala"></root>');
$root['b'] = 'hello'; # <root a="vala" b="hello"/>

边缘大小写使用空字符串("")或NULL,因为simplexml会错误地说明没有名称的属性无效。有意义,因为属性必须有一个名称:

  

警告:main():无法在...中编写或创建未命名的属性

另一个更特殊的案例是__toString magic method的支持。如果将对象作为偏移量传递,SimpleXML将尝试通过魔术方法将其转换为字符串。然后它将使用返回的字符串,如上所述。


总结一下: SimpleXMLElement类没有实现ArrayAccess接口,但因为它是一个内部类,所以它可以添加类似于数组的行为。而SimpleXML就是这样做的。

PHP源代码中的实用程序函数称为sxe_prop_dim_read


但是当你想和你的班级做类似的事情呢?

这就是ArrayAccess接口的用途。在您自己的类中实现它。 PHP已经在内部为你做了一些工作,使偏移更像数组:整数保持整数;像整数一样的字符串转换为整数,布尔值转换为整数。

但是ArrayAccess允许的不仅仅是标准数组:有效的偏移量是浮点数,NULL,数组和对象。

特别是对于NULL,您无法在设置偏移量NULL或设置新元素之间有所区别 - 两种情况都会提供NULL作为偏移量。

接口的示例实现可用另一个问题:PHP, SPL, ArrayAccess Interface

答案 3 :(得分:0)

我猜这是神奇的方法__get()

编辑:我想我错了。还不知道Array Access接口。