2012-03-10 28 views
40

In PHP, posso specificare letterali di array abbastanza facilmente:PHP letterale

array(
    array("name" => "John", "hobby" => "hiking"), 
    array("name" => "Jane", "hobby" => "dancing"), 
    ... 
) 

Ma cosa succede se voglio array di oggetti? Come posso specificare un oggetto letterale in PHP? I.e. in javascript sarebbe:

[ 
    {name: "John", hobby: "hiking"}, 
    {name: "Jane", hobby: "dancing"} 
] 
+4

Non esiste alcun oggetto letterale in PHP. – BoltClock

+1

@ ŠimeVidas, non capisco il tuo commento. Gli oggetti JS sono array associativi, ma gli array associativi PHP non sono oggetti. Anche PHP non è un linguaggio ECMAScript, e PHP non è nemmeno JS. –

+0

@DmitryZorin vedo. Ho pensato che le matrici associative PHP * fossero * oggetti (come in JavaScript). –

risposta

64

Come BoltClock menzionato non c'è un oggetto letterale in PHP tuttavia è possibile fare questo tipo semplicemente gettando le matrici di oggetti:

$testArray = array(
    (object)array("name" => "John", "hobby" => "hiking"), 
    (object)array("name" => "Jane", "hobby" => "dancing") 
); 

echo "Person 1 Name: ".$testArray[0]->name; 
echo "Person 2 Hobby: ".$testArray[1]->hobby; 
+2

bel trucco Tim, grazie – TMS

+1

Fantastico, esattamente la soluzione che volevo! – defines

+10

Si noti che gli oggetti vengono sempre passati per riferimento, gli array no. Pertanto, la modifica di un attributo di un oggetto lo modifica ovunque l'oggetto sia stato assegnato. Questo non è il caso per gli array; rimangono indipendenti. –

0

In PHP, è necessario creare un'istanza prima di poter utilizzare una classe. Ovviamente puoi mettere le istanze in un array in un secondo momento.

4

Un altro modo sarebbe quello di utilizzare il __set_state() metodo magico:

$object = stdClass::__set_state (array (
    'height' => -10924, 
    'color' => 'purple', 
    'happy' => false, 
    'video-yt' => 'AgcnU74Ld8Q' 
)); 

Some more on the __set_state() method, where is it coming from and how is it supposed to be used.

+2

-1, Sarebbe bello se funzionasse. Tuttavia, 'stdClass' non ha un metodo definito' __set_state'. – Shad

+0

http://www.php.net/manual/en/language.oop5.magic.php#object.set-state –

+0

@Shad, vero. Cos'è una soluzione alternativa? – Pacerier

52

Dal PHP 5.4 è anche possibile utilizzare la sintassi di breve matrice:

$json = [ 
    (object) ['name' => 'John', 'hobby' => 'hiking'], 
    (object) ['name' => 'Jane', 'hobby' => 'dancing'], 
]; 
+3

eccellente, questo rende gli script molto più puliti –

0

Se hai intenzione di definire moduli nel modello oggetto letterale "come JavaScript", si potrebbe fare qualcosa di simile:

$object = (object) [ 
    'config' => (object) [ 
     'username' => 'Rob Bennet', 
     'email' => '[email protected]' 
    ], 

    'hello' => function() use(&$object) { 
     return "Hello " . $object->config->username . ". "; 
    }, 

    'emailDisplay' => function() use(&$object) { 
     return "Your email address is " . $object->config->email; 
    }, 

    'init' => function($options) use(&$object) { 
     $object->config = $options; 
     $doUsername = $object->hello; 
     $doEmail = $object->emailDisplay; 
     return $doUsername() . $doEmail(); 
    } 
]; 

$sayMyInfo = $object->init; 

echo $sayMyInfo((object) [ 
    'username' => 'Logan', 
     'email' => '[email protected]' 
]); 

In questo tipo di scenario modulare, di solito optare per la facade pattern, solo che mi piace scrivere le mie chiamate nel seguente modo:

Module::action()->item; 

o

Post::get()->title; 

Nessuno di questi modelli rende facile (o persino possibile a volte) il test. Ma questa è solo una prova di concetto. Tecnicamente, "no" non esiste alcun oggetto letterale in PHP, ma se si è abituati alla sintassi JavaScript (che io sono più di PHP), è possibile simularlo e farlo. Come puoi vedere, è molto più pacchiano in PHP che in JavaScript.

6

Come altri hanno notato, non esiste alcun oggetto letterale in PHP, ma è possibile "simularlo" convertendo una matrice in un oggetto.

Con PHP 5.4, questo è ancora più conciso, perché arrays can be declared with square brackets. Per esempio:

$obj = (object)[ 
    "foo" => "bar", 
    "bar" => "foo", 
]; 

Questo darebbe un oggetto con proprietà "bar" "pippo" e. Tuttavia, non penso che questo fornisca davvero molto vantaggio sull'uso di array associativi. È solo una differenza di sintassi.

Considera di abbracciare l'unicità e il "sapore" di tutte le lingue che utilizzi. In JavaScript, i letterali degli oggetti sono dappertutto. In PHP, gli array associativi sono funzionalmente uguali ai letterali degli oggetti JavaScript, sono facili da creare e sono ben compresi da altri programmatori PHP. Penso che tu stia meglio abbracciando questo "sapore" piuttosto che cercare di farlo sentire come la sintassi letterale dell'oggetto di JavaScript.

0

Il mio modo di letterali oggetto in stile JavaScript in PHP è la seguente:

Per prima cosa creare un array associativo in questo modo:

$test = array(
    'name' => "test", 
    'exists' => true 
); 

Poi ho facilmente rendere un oggetto come questo:

$test = (object)$test; 

ora è possibile testare:

echo gettype($test); // "object" 
echo $test->name; // "test" 
0

Sebbene il cast come oggetto (oggetto) funzioni bene su un singolo livello gerarchico, non approfondisce. In altre parole, se vogliamo che gli oggetti ad ogni livello, avremmo dovuto fare qualcosa di simile:

$foods = (object)[ 
    "fruits" => (object)["apple" => 1, "banana" => 2, "cherry" => 3], 
    "vegetables" => (object)["asparagus" => 4, "broccoli" => 5, "carrot" => 6] 
]; 

Tuttavia, invece di fare fusione multipla come oggetti, siamo in grado di avvolgere il tutto in un json_encode e json_decode come this:

$foods = json_decode(json_encode([ 
    "fruits" => ["apple" => 1, "banana" => 2, "cherry" => 3], 
    "vegetables" => ["asparagus" => 4, "broccoli" => 5, "carrot" => 6] 
])); 

Questo assicura che si tratti di un oggetto al livello più profondo.