Opretter du standardobjekt fra tom værdi i PHP?
On december 1, 2020 by adminOvervej 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, hvor jeg “d gerne tilføje egenskaber til et objekt, et par lag dybt ad gangen, mens det gentager sig gennem nogle andre data. Hvis det ikke findes, opretter det bare det, hvis det gør det, tilsidesætter det. PERFEKT!
Desværre kaster dette advarslen:
Oprettelse af standardobjekt fra tom værdi
Jeg kunne løse problemet ved først at kontrollere, om ejendommen eksisterer sådan:
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 mit ideal opløsning. Jeg spekulerer på, om der er en mere elegant løsning. I øjeblikket bruger jeg dette:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
for at undertrykke advarslerne, men jeg er bekymret for kompatibilitet i fremtiden.
Gør det ikke er der nogen, der har en mere elegant løsning på dette scenario?
Kommentarer
- Brug ikke ' t brug arrays som svaret nedenfor antyder, brug objektet korrekt. Arrays er kun gode til lokal kode, delt uden for en fil eller klasse betyder, at du skriver nøgler manuelt, skal huske dem, gå glip af en eller to, skrivefejl. God IDE med automatisk komplet og objekter med getter / setter er en glad dev verden.
Svar
Ja, brug arrays.
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
Under alle omstændigheder konverterer objektkonvertering kun det yderste array. De indlejrede arrays er stadig arrays.
\is_array($car->general); // true
Hvorfor skal du alligevel have formløse objekter? Enten definer klasser for disse objekter eller behandl dem som arrays er det enkle svar.
Btw $car->{"other"}
er virkelig underlig måde at skrive $car->other
…
Kommentarer
- Jeg antager, at du ' har ret, jeg bare hader at blive låst inde i arrays hele tiden.
$car->{'other'}
skyldes, at de fleste af mine ejendomsnøgler kommer fra strengvariabler. såsom$car->{$var1}->{$var2}
Svar
Ja, du kan undgå de itererede betingede operationer ved at behandle alle data som arrays.
Kode: ( Demo )
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
Når du kun skjuler det øverste niveau fra objekttype til array-type, kan du bare caste det med (array)
. Hvis du har brug for at konvertere alle niveauer – json koder hele objektet, derefter afkode strengen til en matrix. Når du er færdig med at behandle, skal du bruge json_
-funktionerne til at gendanne dataene til objekttype.
Jeg finder det stadig lidt klodset (måske lige så klodset som din betinget tilgang). Fordelen ved ovenstående er i rekursionen; hvis din datadybde ændres, behøver du ikke ændre behandlingsscriptet. Spørg dig selv, om du faktisk har brug for at bruge et objekt. Hvis kodning er forenklet med en anden datatype, kan du måske tænke igen / refactor.
Ps DEFINITIVT skriv ikke stfu-operatøren (@
) i din kode. I næsten alle implementeringer er teknikken undgåelig (dette er en af disse tilfælde), og projekter med sådan syntaks kategoriseres / formodes at være af lav kvalitet af kyndige udviklere.
Kommentarer
- Tak, god vurdering. Jeg kunne desværre ikke vælge andet end objekter, da en tidligere programmør har kodet det som sådan.
Skriv et svar