Vytváření výchozího objektu z prázdné hodnoty v PHP?
On 1 prosince, 2020 by adminZvažte následující kód.
$car = (object)[ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car->{"other"}->{"exterior"}->{$key} = $prop; }
Toto je scénář, kdy bych rád přidává vlastnosti k objektu, několik vrstev hluboko najednou, zatímco iteruje některými dalšími daty. Pokud neexistuje, pouze jej vytvoří, pokud to udělá, přepíše. PERFEKTNÍ!
Bohužel to způsobí varování:
Vytvoření výchozího objektu z prázdné hodnoty
Problém bych mohl vyřešit tak, že nejprve zkontroluji, zda vlastnost existuje:
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; }
To není můj ideální řešení. Zajímalo by mě, jestli existuje elegantnější řešení. V současné době používám toto:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
potlačit varování, ale obávám se o kompatibilitu v budoucnu.
má někdo elegantnější řešení tohoto scénáře?
Komentáře
- Nepoužívejte ' pole jako odpověď níže naznačuje, používat objekt správně. Pole jsou vhodná pouze pro místní kód, sdílená mimo soubor nebo třídu znamená, že píšete klíče ručně, musíte si je pamatovat, vynechat jeden nebo dva, překlep. Dobré IDE s automatickým dokončováním a objekty s getterem / setterem jsou šťastným vývojovým světem.
Odpověď
Ano, použijte pole.
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
Každopádně převod objektu převede pouze nejvzdálenější pole. Vnořená pole jsou stále pole.
\is_array($car->general); // true
Proč vlastně potřebujete, aby to byly beztvaré objekty? Jednoduchá odpověď je buď definovat třídy pro tyto objekty, nebo s nimi zacházet jako s poli.
Btw $car->{"other"}
je opravdu zvláštní způsob psaní $car->other
…
Komentáře
- Předpokládám, že máte ' pravdu, jen nenávidět stále zamčené do polí.
$car->{'other'}
je proto, že většina mých klíčů vlastností pochází z řetězcových proměnných. například$car->{$var1}->{$var2}
odpověď
Ano, můžete se vyhnout iterované podmíněné operace zpracováním všech dat jako polí.
Kód: ( Demo )
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
Když pokrýváte pouze nejvyšší úroveň od typu objektu k typu pole, můžete ji jednoduše seslat pomocí (array)
. Pokud potřebujete převést všechny úrovně – json zakóduje celý objekt, pak tento řetězec dekódujte do pole. Po dokončení zpracování použijte funkce json_
k vrácení dat na typ objektu.
Stále mi připadá trochu neohrabaný (možná stejně neohrabaný jako váš podmíněný přístup). Výhoda ve výše uvedeném spočívá v rekurzi; pokud se vaše hloubka dat změní, nebudete muset měnit skript zpracování. Zeptejte se sami sebe, zda ve skutečnosti potřebujete použít objekt. Pokud je kódování zjednodušeno pomocí jiného datového typu, možná byste měli přehodnotit / refactor.
PS DEFINITELNĚ do svého kódu nenapíšete operátor stfu (@
). Téměř u všech implementací se této technice lze vyhnout (jedná se o jeden z těchto případů) a projekty s takovou syntaxí jsou kvalifikovanými vývojáři kategorizovány / považovány za nekvalitní.
Komentáře
- Díky, dobré hodnocení. Bohužel jsem si nemohl vybrat nic jiného než objekty, protože předchozí programátor to tak kódoval.
Napsat komentář