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

Non ho mai visto questo tipo di sintassiPerché questo tipo di istruzione funziona in PHP?

EDIT

Questo sembra più probabilmente una caratteristica, voi ragazzi sa come posso implementare una funzione come questa?

+0

Qualcosa di più specifico? Quale parte della sintassi non hai visto? –

+4

Suppongo che sia il Phonenumbers [] -> parte del numero di telefono – Htbaa

+1

Questo in realtà non genera un errore? : Potresti forse offrire un po 'di più del codice, in particolare la definizione di "Phonenumbers" nella classe? – poke

risposta

7

Sembra che qualcosa di simile al seguente crea un oggettostdClass con la proprietà phonenumber e lo spinge nella matrice $user->Phonenumbers:

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

Non ho mai visto che la sintassi troppo.

+0

Se Phonenumbers è un array, come si può usare la notazione '->' su quello? Confronta con '$ foo = array(); $ foo-> test = 12345; 'genera un avvertimento. –

+0

Oh, forse non si tratta di una sintassi, si spera che una caratteristica, riesci a capire come implementare questo tipo di funzionalità? – ORM

+0

@Tatu Ulmanen: '[]' viene usato nell'array. Ma non so perché '[] ->' sta creando un nuovo oggetto. – Gumbo

6

Gumbo è giusto, ecco un esempio di lavoro:

<?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); 

rendimenti:

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!" 
} 

edit: Va bene, ho trovato qualcosa legato nel manuale di PHP su questo:

Se un oggetto viene convertito in un oggetto, non viene modificato. Se un valore di qualsiasi altro tipo viene convertito in un oggetto, viene creata una nuova istanza della classe integrata stdClass. Se il valore era NULL, la nuova istanza sarà vuota. (source)

Quindi, utilizzando la sintassi -> converte il cosa in un oggetto. Nell'esempio sopra $obj è null, quindi viene creata una nuova istanza vuota e viene impostato il membro foobar.

Osservando l'esempio di matrice, arr[] crea innanzitutto un nuovo elemento di matrice (vuoto), che viene quindi convertito in un oggetto vuoto a causa della sintassi -> e la variabile membro è impostata.

+0

Questo è incredibile! Puoi spiegare perché? – ORM

+0

Dato che funziona anche con oggetti null (seconda parte dell'esempio), ha senso, che la creazione dell'array con '[]' si traduce in questo. Ma non so perché sia ​​possibile accedere a un oggetto non esistente e crearlo al volo con quello. – poke

+1

Tuttavia, notificherà un avviso E_STRICT: * Strict Standards: creazione dell'oggetto predefinito da un valore vuoto * – Gordon

2

php "implicitamente" crea matrici e oggetti quando si utilizzano [] e -> operatori su variabili non definite.

$does_not_exist->foo = 1; 

qui PHP crea un oggetto stdClass e lancia un avvertimento "rigorosa" "Creazione di oggetto predefinito dal valore vuoto". La cosa simile con gli array

$does_not_exist[] = 1; 

funziona stranamente senza un avvertimento, che alcune persone consider tratta di un problema.

1

PHP sarà typecast NULL nel contesto in cui viene utilizzato.

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) {} 

Di conseguenza, quando si fa:

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

la struttura risultante sarà

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

Come ho già detto nei commenti, così facendo è contro E_STRICT standard e rileverà un avviso.

Problemi correlati