Pregunta

En PHP puede usar corchetes en un elemento para acceder a los atributos:

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

Lo extraño es que $id no es una cadena, es otra SimpleXMLElement. ¿Por qué no es una cuerda? Me encuentro usando strval() por todas partes en esto.

¿Cómo funcionan los corchetes? ¿Puedo hacer eso con mis propias clases? No he visto nada en los documentos sobre esto.

¿Fue útil?

Solución

Puede proporcionar Array como acceso a su objeto implementando la interfaz ArrayAccess , que es parte de la biblioteca estándar de PHP. Esta interfaz es una de esas & "; Incluso si no tiene instalada la extensión completa de la biblioteca estándar de PHP, todavía tiene esta interfaz disponible en PHP 5 &"; cosas.

Al implementar esta interfaz y definir cuatro métodos para su clase

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

debería poder utilizar corchetes con sus objetos instanciados.

En cuanto a SimpleXML en sí, no estoy seguro de si realmente implementa la interfaz ArrayAccess, o si hay algo más detrás de escena en la fuente PHP que le da estos súper poderes.

Otros consejos

Creo que puede extender la clase SimpleXML e implementar ArrayAccess en eso.

En cuanto a SimpleXML en sí, es una clase interna. La única interfaz que implementa para el espacio de usuario de PHP es Traversable .

Internamente cuando se accede con corchetes, SimpleXML busca cosas según el valor y el tipo de índice / clave.

Si el tipo es entero (largo), intenta encontrar el elemento numerado con índice cero y ofrecer su valor. Si tiene un elemento de nodo concreto como $root para el elemento raíz, $root[0] representará el valor de ese elemento:

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

El elemento raíz es un poco poco interesante porque solo existe uno. Es más interesante con elementos que tienen padres.

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

Establece el valor de nodo del primer elemento child. Un índice ascendente agregará un nuevo elemento secundario:

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

Esto funciona más o menos como con las matrices. Las cadenas que son un número entero, funcionan como un número entero:

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

Y dejando los corchetes vacíos, agregará un nuevo elemento al final:

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

Hasta ahora para enteros y " no " compensar. Al igual que con una matriz PHP estándar, esto no debe confundirse con pasar NULL. Se convertiría en una cadena vacía "".

Con cualquier cadena, SimpleXML buscará un nodo de atributo en lugar de un nodo de elemento hijo:

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

Esto también funciona para agregar atributos:

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

Un caso de borde está usando una cadena vacía (__toString) o SimpleXMLElement porque simplexml se equivoca diciendo que un atributo sin nombre no es válido. Tiene sentido ya que los atributos deben tener un nombre:

  

Advertencia: main (): No se puede escribir o crear un atributo sin nombre en ...

Otro caso más especial es el soporte del ArrayAccess método mágico . Si pasa un objeto como desplazamiento, SimpleXML intentará convertirlo en cadena a través del método mágico. Luego usará la cadena devuelta como se describió anteriormente.


Para resumir: La clase sxe_prop_dim_read no implementa la <=> interfaz pero como es una clase interna, puede agregar un comportamiento similar a la matriz. Y SimpleXML hace exactamente eso.

La función de utilidad en las fuentes PHP se llama <=> .


¿Pero qué pasa cuando quieres hacer algo similar con tus clases?

Para eso está la interfaz <=>. Impleméntalo en tus propias clases. PHP ya toma parte del trabajo internamente para que las compensaciones sean más parecidas a una matriz: integer stay integer; una cadena como un entero se convierte en entero y los booleanos se convierten en entero.

Sin embargo, <=> permite más que una matriz estándar: las compensaciones válidas son flotantes, NULL, matrices y objetos.

Especialmente con <=>, no puede diferenciar entre establecer el desplazamiento <=> o establecer un nuevo elemento; ambos casos proporcionarán <=> como desplazamiento.

Un ejemplo de implementación de la interfaz está disponible con otra pregunta: PHP, SPL, ArrayAccess Interface .

Supongo que es el método mágico __ get ()

Editar: creo que adiviné mal. Todavía no conocía la interfaz de Array Access.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top