Creazione di un oggetto predefinito da un valore vuoto in PHP?
Su Dicembre 1, 2020 da adminConsidera il seguente codice.
$car = (object)[ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car->{"other"}->{"exterior"}->{$key} = $prop; }
Questo è uno scenario in cui I “d come aggiungere proprietà a un oggetto, pochi strati in profondità alla volta, mentre iterando attraverso altri dati. Se non esiste, lo creerà semplicemente, se lo farà sovrascriverà. PERFETTO!
Sfortunatamente, questo genererà lavvertimento:
Creazione di un oggetto predefinito da un valore vuoto
Potrei risolvere il problema controllando prima se la proprietà esiste in questo modo:
foreach($exteriorProperties as $key => $prop){ if(!isset($car->other)) $car->other = (object)[]; if(!isset($car->other->exterior)) $car->other->exterior = (object)[]; $car->other->exterior->{$key} = $prop; }
Questo non è il mio ideale soluzione. Mi chiedo se esiste una soluzione più elegante. Attualmente, sto usando questo:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
per sopprimere gli avvisi, ma sono preoccupato per la compatibilità in futuro.
Sì qualcuno ha una soluzione più elegante per questo scenario?
Commenti
- Non ' t utilizzare gli array come la risposta sotto suggerisce, usa loggetto correttamente. Gli array sono utili solo per il codice locale, condivisi allesterno di un file o di una classe significa che stai scrivendo le chiavi manualmente, devi ricordarle, perderne una o due, errore di battitura. Un buon IDE con completamento automatico e oggetti con getter / setter sono un mondo di sviluppo felice.
Answer
Sì, usa gli array.
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
Ad ogni modo, la conversione delloggetto convertirà solo larray più esterno. Gli array annidati sono ancora array.
\is_array($car->general); // true
Perché hai bisogno che siano comunque oggetti informi? Definire classi per quegli oggetti o trattarli come array è la risposta più semplice.
Btw $car->{"other"}
è un modo davvero strano di scrivere $car->other
…
Commenti
- Suppongo che ' abbia ragione, solo odio rimanere bloccato negli array tutto il tempo.
$car->{'other'}
è perché la maggior parte delle mie chiavi di proprietà proviene da variabili stringa. come$car->{$var1}->{$var2}
Risposta
Sì, puoi evitare le operazioni condizionali iterate elaborando tutti i dati come array.
Codice: ( Demo )
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
Quando si converte solo il livello superiore da tipo di oggetto a tipo di matrice, è possibile eseguirne il cast con (array)
. Se è necessario convertire tutti i livelli, json codifica lintero oggetto, quindi decodifica quella stringa in un array. Al termine dellelaborazione, utilizza le funzioni json_
per ripristinare i dati al tipo di oggetto.
Lo trovo ancora un po goffo (forse altrettanto goffo come il tuo approccio condizionale). Il vantaggio di cui sopra è nella ricorsione; se la profondità dei dati cambia, non è necessario modificare lo script di elaborazione. Chiediti se effettivamente hai bisogno di utilizzare un oggetto. Se la codifica è semplificata con un diverso tipo di dati, forse ripensa / refactor.
Ps SICURAMENTE non scrivere loperatore stfu (@
) nel tuo codice. In quasi tutte le implementazioni, la tecnica è evitabile (questo è uno di quei casi) e i progetti con tale sintassi sono classificati / presunti come di bassa qualità da sviluppatori esperti.
Commenti
- Grazie, buona valutazione. Sfortunatamente non ho potuto scegliere altro che oggetti poiché un programmatore precedente lo ha codificato come tale.
Lascia un commento