在 PHP 中,您可以在元素上使用方括号来访问属性:
$node = /* SimpleXMLElement */
$id = $node['id'];
奇怪的是,这$id
不是一个字符串,而是另一个SimpleXMLElement
. 为什么不是字符串?我发现自己strval()
到处都在使用它。
方括号是如何工作的?我可以用自己的课程做到这一点吗?我在文档中没有看到任何关于此的内容。
您可以通过实现ArrayAccess 接口(它是 PHP 标准库的一部分)来提供对对象的类似 Array 的访问。这个接口是“即使你没有安装完整的 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 源代码的幕后发生了其他事情,赋予了它这些超能力。
我相信您可以扩展 SimpleXML 类,并在其中实现 ArrayAccess。
至于 SimpleXML 本身,它是一个内部类。它为 PHP 用户空间实现的唯一接口是Traversable
.
在内部使用方括号访问时,SimpleXML 根据索引/键的值和类型查找内容。
如果类型是整数(长整数),则尝试查找零索引、编号的元素并提供其值。如果您有一个具体的节点元素,例如$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
元素的节点值。一个 index 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
魔术方法的支持。如果您将对象作为偏移量传递,SimpleXML 将尝试通过魔术方法将其转换为字符串。然后它将使用返回的字符串,如上所述。
总结:该类SimpleXMLElement
没有实现ArrayAccess
接口,但由于它是一个内部类,它可以添加类似数组的行为。而 SimpleXML 正是这样做的。
PHP 源代码中的实用程序函数称为sxe_prop_dim_read
.
但是当你想对你的类做类似的事情时呢?
这就是ArrayAccess
接口的用途。在您自己的类中实现它。PHP 已经在内部为您完成了一些工作,以使偏移量更像数组:整数保持整数;像整数这样的字符串被转换为整数,布尔值被转换为整数。
然而ArrayAccess
,允许的不仅仅是标准数组:有效的偏移量是浮点数、NULL、数组和对象。
特别是使用NULL
,您无法区分设置偏移量NULL
或设置新元素 - 两种情况都将提供NULL
偏移量。
另一个问题提供了接口的示例实现:PHP、SPL、ArrayAccess 接口。
我想这是魔术方法__get()
编辑:我想我猜错了。还不知道数组访问接口。