在PHP中,您可以在元素上使用方括号来访问属性:
$node = /* SimpleXMLElement */
$id = $node['id'];
奇怪的是$id
不是字符串,而是另一个SimpleXMLElement
。为什么不是一个字符串?我发现自己在这个地方使用了strval()
。
方括号如何工作?我可以用自己的课程吗?我没有在文档中看到任何关于此事的内容。
答案 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接口。