Lager du standardobjekt fra tom verdi i PHP?
On desember 1, 2020 by adminVurder følgende kode.
$car = (object)[ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car->{"other"}->{"exterior"}->{$key} = $prop; }
Dette er et scenario der jeg «d liker å legge til egenskaper til et objekt, noen få lag dypt av gangen, mens det gjentas gjennom noen andre data. Hvis det ikke finnes, vil det bare opprette det, hvis det gjør det, vil det overstyre. PERFEKT!
Dessverre vil dette kaste advarselen:
Opprette standardobjekt fra tom verdi
Jeg kunne løse problemet ved først å sjekke om eiendommen eksisterer slik:
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; }
Dette er ikke mitt ideal løsning. Jeg lurer på om det er en mer elegant løsning. For tiden bruker jeg dette:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
for å undertrykke advarslene, men jeg er bekymret for kompatibilitet i fremtiden.
Gjør det er det noen som har en mer elegant løsning på dette scenariet?
Kommentarer
- Ikke bruk ' t bruke arrays som svaret nedenfor antyder, bruk objektet riktig. Arrays er bare bra for lokal kode, delt utenfor en fil eller klasse betyr at du skriver nøkler manuelt, må huske dem, savner en eller to, skrivefeil. God IDE med automatisk komplettering og objekter med getter / setter er en lykkelig dev-verden.
Svar
Ja, bruk arrays.
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
Uansett vil objektkonvertering bare konvertere den ytterste matrisen. De nestede matriser er fortsatt matriser.
\is_array($car->general); // true
Hvorfor trenger du det for å være formløse objekter uansett? Enten definer klasser for disse objektene eller behandle dem som matriser er det enkle svaret.
Btw $car->{"other"}
er veldig rar måte å skrive $car->other
…
Kommentarer
- Jeg antar at du ' har rett, jeg bare hater å bli låst i matriser hele tiden.
$car->{'other'}
er fordi de fleste eiendomsnøklene mine kommer fra strengvariabler. slik som$car->{$var1}->{$var2}
Svar
Ja, du kan unngå de itererte betingede operasjonene ved å behandle alle data som matriser.
Kode: ( Demo )
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
Når du bare skjuler det øverste nivået fra objekttype til array-type, kan du bare kaste det med (array)
. Hvis du trenger å konvertere alle nivåer – koder json hele objektet, og dekoder strengen til en matrise. Når du er ferdig med behandlingen, bruk json_
-funksjonene for å tilbakestille dataene til objekttype.
Jeg synes fortsatt dette er litt klumpete (kanskje like klumpete som din betinget tilnærming). Fordelen i ovenstående er i rekursjonen; hvis datadypen din endres, trenger du ikke endre behandlingsskriptet. Spør deg selv om du faktisk trenger å bruke et objekt. Hvis koding er forenklet med en annen datatype, kan du tenke nytt / refactor.
Ps DEFINITIVT ikke skriv stfu-operatøren (@
) i koden din. I nesten alle implementeringer kan teknikken unngås (dette er en av disse tilfellene) og prosjekter med slik syntaks er kategorisert / antatt som lav kvalitet av kunnskapsrike utviklere.
Kommentarer
- Takk, god vurdering. Jeg kunne dessverre ikke velge annet enn objekter siden en tidligere programmerer har kodet den som sådan.
Legg igjen en kommentar