2010-02-21 10 views
13
$user->Phonenumbers[]->phonenumber = '123 123'; 
$user->Phonenumbers[]->phonenumber = '456 123'; 
$user->Phonenumbers[]->phonenumber = '123 777'; 

nunca he visto este tipo de sintaxis¿Por qué este tipo de afirmación funciona en PHP?

EDITAR

Esto parece más probable que una característica, es lo que ustedes saben cómo puedo implementar una función como esta?

+0

¿Algo más específico? ¿Qué parte de la sintaxis no has visto? –

+4

Supongo que es el Phonenumbers [] -> número de pieza – Htbaa

+1

¿Esto no arroja un error? : o ¿Podría ofrecer un poco más del código, especialmente la definición de 'Phonenumbers' en la clase? – poke

Respuesta

7

Parece que algo como lo siguiente crea un objetostdClass con la propiedad del número de teléfono y lo empuja en la matriz $user->Phonenumbers:

$user->Phonenumbers[]->phonenumber = 12345; 

nunca he visto que la sintaxis también.

+0

Si Phonenumbers es una matriz, ¿cómo se puede usar la notación '->'? Compare con '$ foo = array(); $ foo-> test = 12345; 'da como resultado una advertencia. –

+0

Oh, tal vez no es una sintaxis, con suerte una característica, ¿puedes descubrir cómo implementar este tipo de características? – ORM

+0

@Tatu Ulmanen: '[]' se usa en la matriz. Pero no sé por qué '[] ->' está creando un nuevo objeto. – Gumbo

6

Gumbo es la derecha, aquí es un ejemplo de trabajo:

<?php 
class Test 
{ 
    public $arr = array(); 
    public $obj = null; 
} 
$a = new Test(); 
$a->arr[]->foo = 1234; 
$a->arr[]->bar = 'test'; 
var_dump($a->arr); 

// even more weird on null objects 
$a->obj->foobar = 'obj was null!'; 
var_dump($a->obj); 

devuelve:

array(2) { 
    [0]=> 
    object(stdClass)#2 (1) { 
    ["foo"]=> 
    int(1234) 
    } 
    [1]=> 
    object(stdClass)#3 (1) { 
    ["bar"]=> 
    string(4) "test" 
    } 
} 
object(stdClass)#4 (1) { 
    ["foobar"]=> 
    string(13) "obj was null!" 
} 

edición: Vale, he encontrado algo relacionado en el manual de PHP en esto:

Si un objeto se convierte en un objeto, no se modifica. Si un valor de cualquier otro tipo se convierte en un objeto, se crea una nueva instancia de la clase incorporada stdClass. Si el valor era NULL, la nueva instancia estará vacía. (source)

Así, utilizando la sintaxis -> convierte la cosa en un objeto. En el ejemplo anterior $obj es nulo, por lo que se crea una nueva instancia vacía y se establece el miembro foobar.

Al observar el ejemplo de matriz, arr[] primero crea un nuevo elemento de matriz (vacío), que luego se convierte en un objeto vacío debido a la sintaxis -> y se establece la variable de miembro.

+0

¡Esto es increíble! ¿Puedes explicar por qué? – ORM

+0

Dado que incluso funciona con objetos nulos (segunda parte del ejemplo), tiene sentido que la creación de la matriz con '[]' resulte en esto. Pero no sé por qué incluso puedes acceder a un objeto que no existe y crearlo sobre la marcha con eso. – poke

+1

Levantará un aviso de E_STRICT sin embargo: * Estándares estrictos: Crear un objeto predeterminado a partir del valor vacío * – Gordon

2

php "implícitamente" crea matrices y objetos cuando se utilizan operadores [] y -> en variables no definidas.

$does_not_exist->foo = 1; 

aquí php crea un objeto stdClass y se emite una advertencia de "estricta" "Creación de objeto por defecto del valor vacío". La cosa similar con matrices

$does_not_exist[] = 1; 

funciona extrañamente sin una advertencia, que algunas personas consider de un error.

1

PHP convertirá NULL al contexto en el que se utiliza.

var_dump((bool) NULL); 
var_dump((int) NULL); 
var_dump((float) NULL); 
var_dump((string) NULL); 
var_dump((array) NULL); 
var_dump((object) NULL); 

dará

bool(false) 
int(0) 
float(0) 
string(0) "" 
array(0) {} 
object(stdClass)#1 (0) {} 

En consecuencia, cuando se hace:

$a = NULL; 
$a[] = NULL;  // used in array context `[]` 
$a[0]->foo = NULL; // object context `->` 
$a[0]->foo++;  // number context `++` 

la estructura resultante será

array(1) { 
    [0]=> 
    object(stdClass)#1 (1) { 
    ["foo"]=> 
    int(1) 
    } 
} 

Como he mencionado en los comentarios, si lo hace es contra E_STRICT sin embargo, y se enviará un aviso.

Cuestiones relacionadas