Tworzysz domyślny obiekt z pustej wartości w PHP?
On 1 grudnia, 2020 by adminWeź pod uwagę następujący kod.
$car = (object)[ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car->{"other"}->{"exterior"}->{$key} = $prop; }
To jest scenariusz, w którym ja „d lubią dodawać właściwości do obiektu, kilka warstw na raz, podczas iteracji przez inne dane. Jeśli nie istnieje, po prostu go utworzy, jeśli tak, zastąpi. IDEALNIE!
Niestety, spowoduje to wyświetlenie ostrzeżenia:
Tworzenie domyślnego obiektu z pustej wartości
Mogłem rozwiązać problem, sprawdzając najpierw, czy właściwość istnieje w ten sposób:
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 nie jest mój ideał rozwiązanie. Zastanawiam się, czy istnieje bardziej eleganckie rozwiązanie. Obecnie „używam tego:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
do pomijania ostrzeżeń, ale martwię się o kompatybilność w przyszłości.
Czy czy ktoś ma bardziej eleganckie rozwiązanie tego scenariusza?
Komentarze
- Nie ' nie używaj tablic jako odpowiedź poniżej sugeruje, użyj obiektu poprawnie. Tablice są dobre tylko dla kodu lokalnego, udostępniane poza plikiem lub klasą oznacza, że wpisujesz klucze ręcznie, musisz je zapamiętać, przegapić jeden lub dwa, literówka. Dobre IDE z autouzupełnianiem i obiekty z getter / setter to szczęśliwy świat deweloperów.
Odpowiedź
Tak, użyj tablic.
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
W każdym razie konwersja obiektu spowoduje konwersję tylko najbardziej zewnętrznej tablicy. Tablice zagnieżdżone są nadal tablicami.
\is_array($car->general); // true
Dlaczego i tak potrzebujesz, aby były to obiekty bezkształtne? Prostą odpowiedzią jest zdefiniowanie klas dla tych obiektów lub traktowanie ich jako tablic.
Btw $car->{"other"}
to naprawdę dziwny sposób pisania $car->other
…
Komentarze
- Przypuszczam, że ' masz rację, po prostu nienawidzę ciągłego zamykania się w tablicach.
$car->{'other'}
wynika z tego, że większość moich kluczy właściwości pochodzi ze zmiennych łańcuchowych. takie jak$car->{$var1}->{$var2}
Odpowiedź
Tak, możesz uniknąć iterowane operacje warunkowe polegające na przetwarzaniu wszystkich danych jako tablic.
Kod: ( Demo )
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
Gdy konwertujesz tylko najwyższy poziom z typu obiektowego na typ tablicowy, możesz go po prostu rzutować za pomocą (array)
. Jeśli chcesz przekonwertować wszystkie poziomy – json zakoduj cały obiekt, a następnie zdekoduj ten ciąg do tablicy. Po zakończeniu przetwarzania użyj funkcji json_
, aby przywrócić dane do typu obiektowego.
Nadal uważam to za trochę niezgrabne (być może tak samo niezgrabne jak podejście warunkowe). Zaletą powyższego jest rekurencja; jeśli zmieni się głębia danych, nie będziesz musiał zmieniać skryptu przetwarzającego. Zadaj sobie pytanie, czy faktycznie potrzebujesz użyć obiektu. Jeśli kodowanie jest uproszczone za pomocą innego typu danych, być może trzeba przemyśleć / refactor.
Ps DEFINITELY nie wpisuj operatora stfu (@
) do swojego kodu. W prawie wszystkich implementacjach tej techniki można uniknąć (jest to jeden z tych przypadków), a projekty o takiej składni są klasyfikowane / uznawane za niskiej jakości przez doświadczonych programistów.
Komentarze
- Dzięki, dobra ocena. Niestety nie mogłem wybrać niczego poza obiektami, ponieważ poprzedni programista zakodował to jako takie.
Dodaj komentarz