Creați obiect implicit din valoarea goală în PHP?
On decembrie 1, 2020 by adminLuați în considerare următorul cod.
$car = (object)[ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car->{"other"}->{"exterior"}->{$key} = $prop; }
Acesta este un scenariu în care I „d doriți să adăugați proprietăți unui obiect, cu câteva straturi adânc la un moment dat, în timp ce iterați prin alte date. Dacă nu există, îl va crea, dacă îl va face, acesta va suprascrie. PERFECT!
Din păcate, acest lucru va lansa avertismentul:
Crearea obiectului implicit din valoarea goală
Aș putea rezolva problema verificând mai întâi dacă proprietatea există astfel:
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; }
Acesta nu este idealul meu soluţie. Mă întreb dacă există o soluție mai elegantă. În prezent, folosesc acest lucru:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
pentru a suprima avertismentele, dar mă îngrijorează compatibilitatea în viitor.
cineva are o soluție mai elegantă la acest scenariu?
Comentarii
- Nu ' nu utilizați tablouri ca răspunsul de mai jos sugerează, utilizați corect obiectul. Tablourile sunt bune doar pentru codul local, partajate în afara unui fișier sau clasă înseamnă că scrieți chei manual, trebuie să le amintiți, să pierdeți una sau două, să scrieți greșit. IDE bun cu completare automată și obiecte cu getter / setter sunt o lume fericită.
Răspuns
Da, utilizați tablouri.
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
Oricum, conversia obiectului va converti doar matricea exterioară. Matricile imbricate sunt încă matrici.
\is_array($car->general); // true
De ce aveți nevoie ca acestea să fie oricum obiecte fără formă? Fie să definiți clase pentru acele obiecte, fie să le tratați ca tablouri, este răspunsul simplu.
Btw $car->{"other"}
este un mod cu adevărat ciudat de a scrie $car->other
…
Comentarii
- Presupun că ' ai dreptate, tocmai urăsc să fiu blocat tot timpul în matrici.
$car->{'other'}
se datorează faptului că majoritatea cheilor mele de proprietate provin din variabile șir. cum ar fi$car->{$var1}->{$var2}
Răspuns
Da, puteți evita operațiile condiționate iterate prin procesarea tuturor datelor ca tablouri.
Cod: ( Demo )
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
Când acoperiți nivelul superior de la tipul de obiect la tipul de matrice, îl puteți arunca doar cu (array)
. Dacă trebuie să convertiți toate nivelurile – json codifică întregul obiect, apoi decodați acel șir într-o matrice. Când ați terminat de procesat, utilizați funcțiile json_
pentru a readuce datele la tipul de obiect.
Încă mi se pare puțin cam ciudat (poate la fel de ciudat ca abordare condiționată). Beneficiul din cele de mai sus este în recursivitate; dacă profunzimea datelor dvs. se schimbă, nu veți avea nevoie să modificați scriptul de procesare. Întrebați-vă dacă de fapt trebuie să utilizați un obiect. Dacă codificarea este simplificată cu un alt tip de date, probabil că aveți o regândire / refactor.
Ps DEFINITIV nu scrie operatorul stfu (@
) în codul tău. În aproape toate implementările, tehnica este evitabilă (acesta este unul dintre aceste cazuri), iar proiectele cu o astfel de sintaxă sunt clasificate / presupuse ca fiind de calitate scăzută de către dezvoltatorii cunoscuți.
Comentarii
- Mulțumesc, apreciere bună. Din păcate nu am putut alege altceva decât obiecte, deoarece un programator anterior l-a codat ca atare.
Lasă un răspuns