Een standaardobject maken van een lege waarde in PHP?
Geplaatst op december 1, 2020 door adminBeschouw de volgende code.
$car = (object)[ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car->{"other"}->{"exterior"}->{$key} = $prop; }
Dit is een scenario waarin ik “d graag eigenschappen aan een object toevoegen, een paar lagen diep per keer, terwijl het door andere gegevens loopt. Als het niet bestaat, zal het het gewoon creëren, als het dat wel doet, zal het overschrijven. PERFECT!
Helaas genereert dit de waarschuwing:
Een standaardobject maken van een lege waarde
Ik zou het probleem kunnen oplossen door eerst te controleren of de eigenschap zo bestaat:
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; }
Dit is niet mijn ideaal oplossing. Ik vraag me af of er een elegantere oplossing is. Momenteel gebruik ik dit:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
om de waarschuwingen te onderdrukken, maar ik maak me zorgen over compatibiliteit in de toekomst.
Doet heeft iemand een elegantere oplossing voor dit scenario?
Reacties
- Gebruik ' geen arrays als het antwoord hieronder suggereert, gebruik object correct. Arrays zijn alleen goed voor lokale code, gedeeld buiten een bestand of klasse betekent dat u handmatig sleutels schrijft, ze moet onthouden, een of twee moet missen, typefout. Goede IDE met automatisch aanvullen en objecten met getter / setter zijn een gelukkige ontwikkelwereld.
Antwoord
Ja, gebruik arrays.
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
Hoe dan ook, de objectconversie converteert alleen de buitenste array. De geneste arrays zijn nog steeds arrays.
\is_array($car->general); // true
Waarom heb je het eigenlijk nodig als vormloze objecten? Definieer klassen voor die objecten of behandel ze als arrays is het simpele antwoord.
Btw $car->{"other"}
is echt een rare manier van schrijven $car->other
…
Reacties
- Ik neem aan dat je ' gelijk hebt, ik haat het om de hele tijd opgesloten te raken in arrays. De
$car->{'other'}
is omdat de meeste van mijn eigenschapssleutels afkomstig zijn van stringvariabelen. zoals$car->{$var1}->{$var2}
Antwoord
Ja, u kunt vermijden de herhaalde voorwaardelijke bewerkingen door alle gegevens als arrays te verwerken.
Code: ( Demo )
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
Als je alleen het hoogste niveau van objecttype naar array-type bedekt, kun je het gewoon casten met (array)
. Als u alle niveaus moet converteren, codeert json het hele object en decodeert u die tekenreeks naar een array. Als je klaar bent met verwerken, gebruik dan json_
functies om de gegevens terug te zetten naar het objecttype.
Ik vind dit nog steeds een beetje onhandig (misschien net zo onhandig als je voorwaardelijke benadering). Het voordeel in het bovenstaande zit in de recursie; als uw gegevensdiepte verandert, hoeft u het verwerkingsscript niet te wijzigen. Vraag uzelf af of u daadwerkelijk een object moet gebruiken. Als codering wordt vereenvoudigd met een ander gegevenstype, moet u misschien opnieuw nadenken / refactor.
Ps schrijf ZEKER de stfu-operator (@
) in uw code. In bijna alle implementaties is de techniek te vermijden (dit is een van die gevallen) en projecten met een dergelijke syntaxis worden door ervaren ontwikkelaars gecategoriseerd / verondersteld als lage kwaliteit.
Opmerkingen
- Bedankt, goede beoordeling. Ik kon helaas niets anders kiezen dan objecten omdat een vorige programmeur het als zodanig heeft gecodeerd.
Geef een reactie