Skapa standardobjekt från tomt värde i PHP?
On december 1, 2020 by adminTänk på följande kod.
$car = (object)[ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car->{"other"}->{"exterior"}->{$key} = $prop; }
Detta är ett scenario där jag ”d gillar att lägga till egenskaper till ett objekt, några lager djupt åt gången, medan det går igenom någon annan data. Om det inte finns kommer det bara att skapa det, om det gör det kommer det att åsidosätta. PERFEKT!
Tyvärr kommer detta att varna:
Skapa standardobjekt från tomt värde
Jag kunde lösa problemet genom att först kontrollera om egenskapen finns så:
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; }
Detta är inte mitt ideal lösning. Jag undrar om det finns en mer elegant lösning. För närvarande använder jag detta:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
för att undertrycka varningarna men jag är orolig för kompatibilitet i framtiden.
Gör det har någon en mer elegant lösning på det här scenariot?
Kommentarer
- Inte ' t använda arrays som svaret nedan föreslår, använd objektet ordentligt. Arrayer är bara bra för lokal kod, delas utanför en fil eller klass betyder att du skriver nycklar manuellt, måste komma ihåg dem, missa en eller två, skrivfel. Bra IDE med automatisk komplettering och objekt med getter / setter är en lycklig dev-värld.
Svar
Ja, använd matriser.
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
Hur som helst kommer objektkonverteringen bara att konvertera den yttersta matrisen. De kapslade matriserna är fortfarande matriser.
\is_array($car->general); // true
Varför behöver du det för att vara formlösa objekt ändå? Antingen definiera klasser för dessa objekt eller behandla dem som arrays är det enkla svaret.
Btw $car->{"other"}
är verkligen konstigt sätt att skriva $car->other
…
Kommentarer
- Jag antar att du ' har rätt, jag bara hatar att bli låst i matriser hela tiden.
$car->{'other'}
beror på att de flesta av mina fastighetsnycklar kommer från strängvariabler. som$car->{$var1}->{$var2}
Svar
Ja, du kan undvika de itererade villkorliga operationerna genom att bearbeta all data som matriser.
Kod: ( Demo )
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
När du bara täcker den översta nivån från objekttyp till arraytyp kan du bara kasta den med (array)
. Om du behöver konvertera alla nivåer – koda json hela objektet och avkoda sedan strängen till en matris. När du är klar med bearbetningen använder du json_
-funktionerna för att återställa data till objekttyp.
Jag tycker fortfarande att det är lite klumpigt (kanske lika klumpigt som ditt villkorligt tillvägagångssätt). Fördelen i ovanstående ligger i rekursionen; om ditt datadjup ändras behöver du inte ändra bearbetningsskriptet. Fråga dig själv om du faktiskt behöver använda ett objekt. Om kodning är förenklad med en annan datatyp kan du kanske tänka om / refactor.
Ps DEFINITIVT skriv inte stfu-operatören (@
) i din kod. I nästan alla implementeringar kan tekniken undvikas (detta är ett av dessa fall) och projekt med sådan syntax kategoriseras / antas vara av låg kvalitet av kunniga utvecklare.
Kommentarer
- Tack, bra bedömning. Jag kunde tyvärr inte välja något annat än objekt eftersom en tidigare programmerare har kodat det som sådant.
Lämna ett svar