Alapértelmezett objektum létrehozása üres értékből a PHP-ben?
On december 1, 2020 by adminVegye figyelembe a következő kódot.
$car = (object)[ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car->{"other"}->{"exterior"}->{$key} = $prop; }
Ez egy olyan forgatókönyv, ahol “d” Szeretne tulajdonságokat hozzáadni egy objektumhoz, egyszerre néhány réteggel, miközben más adatokon keresztül ismétlődik. Ha nem létezik, akkor csak létrehozza, ha mégis, akkor felülírja. TÖKÉLETES!
Sajnos ez eldobja a figyelmeztetést:
Alapértelmezett objektum létrehozása üres értékből
Megoldhatnám a problémát, ha először megvizsgálom, hogy a tulajdonság létezik-e így:
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; }
Ez nem az én ideálom megoldás. Kíváncsi vagyok, van-e elegánsabb megoldás. Jelenleg ezt használom:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
a figyelmeztetések elnyomására, de aggódom a jövőbeni kompatibilitás miatt.
van valakinek elegánsabb megoldása erre a forgatókönyvre?
Megjegyzések
- Ne használja ' a tömböket az alábbi válasz azt sugallja, hogy az objektumot használja megfelelően. A tömbök csak a helyi kódra alkalmasak, fájlon vagy osztályon kívül megosztva azt jelentik, hogy kézzel írod a kulcsokat, emlékezned kell rájuk, el kell hagynod egy vagy kettőt, el kell írniuk. Az automatikus kiegészítéssel ellátott jó IDE és a getter / setter objektumok boldog fejlesztési világot jelentenek.
Válasz
Igen, használjon tömböket.
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
Az objektumkonverzió mindenesetre csak a legkülső tömböt fogja átalakítani. A beágyazott tömbök továbbra is tömbök.
\is_array($car->general); // true
Miért van szükség rá, hogy formátlan objektumok legyenek? Vagy definiáljon osztályokat ezekhez az objektumokhoz, vagy tömbként kezelje őket. Az egyszerű válasz.
A Btw $car->{"other"}
nagyon furcsa írásmód $car->other
…
megjegyzések
- feltételezem, hogy ' igazad van, csak utálok állandóan tömbökbe zárni. A
$car->{'other'}
azért van, mert a tulajdonságkulcsaim nagy része karakterlánc-változókból származik. például$car->{$var1}->{$var2}
Válasz
Igen, elkerülheti az iterált feltételes műveletek az összes adat tömbként történő feldolgozásával.
Kód: ( Demo )
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
Ha csak a legfelső szintet fedi le objektumtípustól tömbtípusig, egyszerűen átküldheti a következővel: (array)
. Ha minden szintet konvertálnia kell – a json kódolja az egész objektumot, majd dekódolja ezt a karakterláncot tömbgé. Ha végzett a feldolgozással, használja a json_
függvényeket az adatok objektumtípusra való visszaállításához.
Ezt még mindig kissé nehézkesnek tartom (talán ugyanolyan nehézkesnek, mint a feltételes megközelítés). A fentiek előnye a rekurzió; ha az adatmélységed megváltozik, akkor nem kell módosítanod a feldolgozó szkriptet. Kérdezd meg magadtól, hogy valóban szükséged van-e egy objektum használatára. Ha a kódolást egy másik adattípussal egyszerűsítjük, érdemes esetleg újragondolni / refactor.
Ps VÉGLEGESEN ne írja be a kódjába az stfu operátort (@
). Szinte minden megvalósításban elkerülhető a technika (ez az egyik ilyen eset), és az ilyen szintaxissal rendelkező projekteket a hozzáértő fejlesztők alacsony kategóriába sorolják / feltételezik.
Megjegyzések
- Köszönöm, jó értékelést. Sajnos nem választhattam mást, csak objektumokat, mivel egy korábbi programozó ezt kódolta.
Vélemény, hozzászólás?