1

PHP では、要素に角括弧を使用して属性にアクセスできます。

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

奇妙なのは$id、これは文字列ではなく、別のSimpleXMLElement. なぜ文字列ではないのですか?私はこれをあちこちで使用strval()していることに気づきました。

角括弧はどのように機能していますか? 自分のクラスでそれを行うことはできますか? 私はこれについてドキュメントで何も見たことがありません。

4

4 に答える 4

3

PHP 標準ライブラリの一部であるArrayAccess インターフェイスを実装することにより、オブジェクトへの配列のようなアクセスを提供できます。このインターフェースは、「完全な PHP 標準ライブラリ拡張機能がインストールされていなくても、PHP 5 でこのインターフェースを使用できる」ものの 1 つです。

このインターフェイスを実装し、クラスに 4 つのメソッドを定義することによって

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 ソースの舞台裏でこれらの超能力を提供する何か他のことが起こっているかどうかはわかりません。

于 2009-03-19T21:59:35.180 に答える
1

SimpleXML クラスを拡張し、その中に ArrayAccess を実装できると思います。

于 2009-03-21T02:06:54.393 に答える
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                     

ルート要素は 1 つしか存在しないため、少し面白くありません。親を持つ要素を使用すると、より興味深いものになります。

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

child最初の要素のノード値を設定します。インデックスを 1 つ上にすると、新しい子が追加されます。

$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(): 名前のない属性を書き込んだり、作成したりできません ...

もう 1 つの特殊なケースは、__toStringマジック メソッドのサポートです。オブジェクトをオフセットとして渡すと、SimpleXML はマジック メソッドを使用してオブジェクトを文字列に変換しようとします。次に、返された文字列を上記のように使用します。


要約すると、SimpleXMLElementクラスはインターフェイスを実装していませんArrayAccessが、内部クラスであるため、配列と同様の動作を追加できます。SimpleXML はまさにそれを行います。

PHP ソースのユーティリティ関数は と呼ばれsxe_prop_dim_readます。


しかし、クラスで同様のことをしたい場合はどうでしょうか?

そのためのArrayAccessインターフェースです。独自のクラスに実装します。PHP は、オフセットをより配列のようにするために、すでに内部でいくつかの作業を行っています。整数のような文字列は整数に変換され、ブール値は整数に変換されます。

ただしArrayAccess、標準の配列以上のものを使用できます。有効なオフセットは、float、NULL、配列、およびオブジェクトです。

特に ではNULL、オフセットの設定と新しい要素の設定を区別することはできません。NULLどちらの場合もNULLオフセットとして提供されます。

インターフェースの実装例は、別の質問で利用できます: PHP, SPL, ArrayAccess Interface .

于 2012-11-05T13:43:50.453 に答える
0

魔法のメソッド__get()だと思います

編集:私は間違っていると思います。Array Access インターフェイスについてまだ知りませんでした。

于 2009-03-19T21:59:36.443 に答える