2009-03-19 3 views
1

당신은 속성에 액세스 할 요소에 대괄호를 사용할 수 있습니다 : 이상한 무엇Simple XML은 [] 연산자를 어떻게 사용합니까? PHP에서

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

$id 문자열되지 않는 것입니다, 그것은 또 다른 SimpleXMLElement입니다. 그것은 왜 문자열이 아닌가요? 나는이 곳의 모든 곳에 strval()을 사용하고있다.

대괄호는 어떻게 작동합니까? 내 수업으로 그걸 할 수 있을까요? 나는 이것에 대해 문서에서 아무 것도 보지 못했다.

답변

3

PHP 표준 라이브러리의 일부인 ArrayAccess interface을 구현하면 객체에 대한 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 소스의 장면에서 진행되는 다른 작업이 있는지 알 수 없습니다.

0

이 나는 ​​마법의 방법을 __get()

편집을 추측 : 내가 잘못 추측 생각합니다. 아직 어레이 액세스 인터페이스를 알지 못했습니다.

1

SimpleXML 클래스를 확장하고 그 안에 ArrayAccess를 구현할 수 있다고 생각합니다.

1

SimpleXML 자체는 내부 클래스입니다. PHP 사용자 공간 용으로 구현 된 유일한 인터페이스는 Traversable입니다.

내부적으로 대괄호로 액세스 할 때 SimpleXML은 색인/키의 값과 유형에 따라 사물을 찾습니다.

형식이 integer (long) 인 경우 0으로 색인화되고 번호가 매겨진 요소를 찾고 해당 값을 제공하려고 시도합니다. 루트 요소에 대한 $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 요소의 노드 값을 설정한다. 새로운 색인을 추가하면 다음과 같이 새 하위 항목이 추가됩니다.

$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 --^ 

그리고 빈 괄호를 떠나, 마지막에 새로운 요소를 추가하지 않습니다 : "NO"오프셋 정수에 대한 지금까지

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

및 . 표준 PHP 배열과 마찬가지로 this를 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이 이름이없는 속성이 유효하지 않다는 오류를 내기 때문입니다.

경고 : 주() : 쓰거나에 ...

또 다른 더욱 특별한 경우가 __toString magic method의 지원이다 익명의 속성을 만들 수 없습니다 속성의 이름이 있어야합니다 같은 의미가 있습니다. 옵셋으로 객체를 전달하면 SimpleXML은이를 매직 메소드를 통해 문자열로 변환하려고합니다. 그런 다음 위에서 설명한대로 반환 된 문자열을 사용합니다.


은 요약하면 : SimpleXMLElement 클래스는 ArrayAccess 인터페이스를 구현하지 않습니다하지만 내부 클래스이기 때문에, 그것은 배열-비슷한 동작을 추가 할 수 있습니다. 그리고 SimpleXML은 정확히 그것을합니다.

PHP 소스의 유틸리티 기능은 sxe_prop_dim_read입니다.


하지만 수업과 비슷한 것을하고 싶다면 어떨까요?

그게 바로 ArrayAccess 인터페이스입니다. 자신의 클래스에서 구현하십시오. PHP는 이미 내부적으로 더 많은 배열과 같은 오프셋을 만들기 위해 다음과 같은 작업을 수행합니다. integer stay integer; 정수와 같은 문자열은 정수로 변환되고 불린은 정수로 변환됩니다.

그러나 ArrayAccess은 표준 배열 이상을 허용합니다. 유효한 오프셋은 실수, NULL, 배열 및 객체입니다.

특히 NULL을 사용하면 오프셋 NULL을 설정하거나 새 요소를 설정하는 것과 차이를 둘 수 없으며 두 경우 모두 오프셋으로 NULL을 제공합니다.

인터페이스의 구현 예는 다른 질문 인 PHP, SPL, ArrayAccess Interface과 함께 사용할 수 있습니다.