Luodaanko oletusobjekti tyhjästä arvosta PHP: ssä?
On joulukuu 1, 2020 by adminHarkitse seuraavaa koodia.
$car = (object)[ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car->{"other"}->{"exterior"}->{$key} = $prop; }
Tämä on skenaario, jossa ”d” haluaisin lisätä objektiin ominaisuuksia, muutama kerros syvä kerrallaan, samalla kun iteroidaan joidenkin muiden tietojen kautta. Jos sitä ei ole, se vain luo sen, jos se tekee, se ohittaa. TÄYDELLINEN!
Valitettavasti tämä heittää varoituksen:
Oletusobjektin luominen tyhjästä arvosta
Voin ratkaista ongelman tarkistamalla ensin, onko ominaisuus olemassa:
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; }
Tämä ei ole minun ihanteellinen ratkaisu. Mietin, onko olemassa tyylikkäämpi ratkaisu. Tällä hetkellä käytän tätä:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
varoitusten estämiseksi, mutta olen huolissani yhteensopivuudesta tulevaisuudessa.
kenelläkään on tyylikkäämpi ratkaisu tähän skenaarioon?
Kommentit
- Älä ' käytä taulukoita alla oleva vastaus ehdottaa, käytä objektia oikein. Taulukot ovat hyviä vain paikalliseen koodiin, jaettu tiedoston tai luokan ulkopuolella tarkoittaa, että kirjoitat avaimet manuaalisesti, sinun täytyy muistaa ne, unohtaa yksi tai kaksi, kirjoitusvirhe. Hyvä IDE automaattisella täydennyksellä ja objektit, joissa on getter / setter, ovat onnellinen kehitysmaailma.
Vastaa
Kyllä, käytä taulukoita.
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
Joka tapauksessa objektimuunnos muuntaa vain uloimman taulukon. Sisäkkäiset taulukot ovat edelleen taulukoita.
\is_array($car->general); // true
Miksi tarvitset sen kuitenkin muotonsa esineitä? Joko määritä luokat kyseisille kohteille tai pidä niitä matriiseina on yksinkertainen vastaus.
Btw $car->{"other"}
on todella outo tapa kirjoittaa $car->other
…
Kommentit
- Oletan, että olet ' oikeassa, minä vain vihaa lukittua taulukoihin koko ajan.
$car->{'other'}
johtuu siitä, että suurin osa ominaisuusavaimista tulee merkkijonomuuttujista. kuten$car->{$var1}->{$var2}
Vastaa
Kyllä, voit välttää iteroidut ehdolliset operaatiot käsittelemällä kaikki tiedot matriiseina.
Koodi: ( Demo )
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
Kun peität vain ylätason objektityypistä taulukotyyppiin, voit suoratoistaa sen valitsemalla (array)
. Jos haluat muuntaa kaikki tasot – json koodaa koko objektin, purkaa sitten merkkijono taulukoksi. Kun käsittely on valmis, käytä json_
-toimintoja palauttaaksesi tiedot objektityypiksi.
Minusta tämä on silti hieman hankala (ehkä yhtä kömpelö kuin sinun ehdollinen lähestymistapa). Edellä olevan etu on rekursio; jos tietosyvyytesi muuttuu, sinun ei tarvitse muuttaa käsittelyskriptiä. Kysy itseltäsi, tarvitseeko todella käyttää objektia. Jos koodausta yksinkertaistetaan toisella tietotyypillä, harkitse ehkä uudelleen / refactor.
Ps ÄLÄ VÄHÄTÄ kirjoita stfu-operaattoria (@
) koodiisi. Lähes kaikissa toteutuksissa tekniikka on vältettävissä (tämä on yksi niistä tapauksista), ja tällaisen syntaksin omaavat projektit luokitellaan / oletetaan huonolaatuisiksi asiantuntevien kehittäjien toimesta.
Kommentit
- Kiitos, hyvä arvio. En valitettavasti voinut valita muuta kuin esineitä, koska edellinen ohjelmoija on koodannut sen sellaiseksi.
Vastaa