A konstruktor tulajdonságai egy új PHP 8 kényelmi funkció, amely segít minimalizálni a kódismétlést. Ez lehetővé teszi a tulajdonságok definiálását és inicializálását egyetlen konstruktor utasításba.
Hagyományos osztály
A konstruktortulajdonság-promóció (innen CPP) az értékobjektumok kontextusában a leghasznosabb. Ezek általában egyszerű osztályok, amelyek leírják az adatszerkezetet. Így nézhet ki a PHP 7.4:
class BlogPost { protected string $Title; protected string $Content; protected DateTimeImmutable $PostedDate; public function __construct( string $Title, string $Content, DateTimeImmutable $PostedDate) { $this -> Title = $Title; $this -> Content = $Content; $this -> PostedDate = $PostedDate; } }
Elég hosszú osztályt hoztunk létre, annak ellenére, hogy csak három tulajdonságunk van! Minden tulajdonságnév négyszer fordul elő, a gépírásokat kétszer írják. Ha módosítania kellene az egyik tulajdonságot, vagy hozzá kellene adnia egyet, akkor három kódsort érintene meg.
Itt van ugyanez a példa, átírva a CPP használatára a PHP 8-ban:
class BlogPost { public function __construct( protected string $Title, protected string $Content, protected DateTimeImmutable $PostedDate) {} }
A CPP használatával drasztikusan csökkentettük osztályunk méretét. Csak egy kódsort kell hozzáadnia vagy módosítania, ha ezzel az osztály tulajdonságokkal dolgozik.
Közelebbről
A CPP egyesíti a tulajdonságmeghatározást a konstruktor paraméterlistájával. Kiemelt tulajdonság létrehozásához tegye előtte a nevét egy osztály láthatóság-módosítóval – public
, protected
vagy private
.
A promóció után az ingatlan úgy viselkedik, mint bármely más osztályú ingatlan. Az osztályon belül elérheti $this -> Property
vagy külsőleg (ha ez a public
ingatlan). Belsőleg a PHP-k egyszerűen átalakítják a kompakt szintaxist a PHP 7 által támogatott sokkal hosszabb verzióvá.
Nem kell a népszerűsített tulajdonságokkal rendelkező tipefinteket használni – elfogadható az írás protected $Title
, például. Alapértelmezett értékeket állíthat be ugyanazzal a szintaxissal, mint egy normál konstruktor paraméter (protected string $Title = "Example Post"
).
Kivitelező karosszéria használata
A kivitelező nem mindig lesz olyan egyszerű, mint a mi példánk. Lehet, hogy el kell végeznie néhány ellenőrzési ellenőrzést, vagy átalakítania kell egy értéket.
A CPP használatakor továbbra is megírhat egy konstruktortestet. A kiemelt tulajdonságok értékeihez akár a kiemelt példányváltozóként, akár a helyi változóval férhet hozzá:
public function __construct(protected string $Title) { if (!$this -> Title) { throw new InvalidArgumentException("Title cannot be empty."); } // OR if (!$Title) { throw new InvalidArgumentException("Title cannot be empty."); } }
Bármelyik megközelítést is választja, a változót vagy a tulajdonságot, ugyanazzal az értékkel fog dolgozni. A PHP egyszerűen elrejti a $this -> Title = $Title
sor, amelyet általában kézzel írna.
Kombinálás a szokásos tulajdonságokkal és paraméterekkel
A népszerűsített tulajdonságokat szabadon keverheti a szokásos tulajdonságmeghatározásokkal. Ezenkívül kombinálhatja a promóciós és a nem támogatott tulajdonságokat a konstruktor paramétereiben.
class BlogPost { public ?DateTimeImmutable $PostedDate = null; public function __construct(public string $Title, bool $isPosted=true) { if ($isPosted) $this -> PostedDate = new DateTimeImmutable(); } }
Legyen óvatos, amikor ezeket a szintaxisokat összekeveri. A népszerűsített tulajdonságok könnyen figyelmen kívül hagyhatók, amikor a kódot átfedik, különösen, ha szabályos osztálytulajdonság-definíciók előzik meg őket. Ha az osztályának már több tulajdonsága van a hagyományos űrlap használatával, akkor az új szintaxis használata egy extra kiegészítéshez nem biztos, hogy a legjobb megközelítés ehhez a fájlhoz.
Attribútumokkal használható
Az egyik a PHP 8-ból egyéb új funkciók attribútumok voltak. Ezek lehetővé teszik extra metaadatok jegyzetelését a kódalapjában lévő entitásokkal szemben.
A promóciós tulajdonságok teljes mértékben támogatják az attribútumokat. Mivel nem egyértelmű, hogy az attribútum vonatkozik-e a tulajdonságmeghatározás vagy a method paraméter, A PHP mindkettőre alkalmazza.
Ez azt jelenti, hogy ugyanazt az értéket kapja vissza, függetlenül attól, hogy a tulajdonságot vagy a konstruktor paraméterét vizsgálja-e. Ez a rugalmas megközelítés biztosítja, hogy a kivitelező tulajdonságainak promóciója révén ne veszítse el az attribútumok funkcionalitását.
Visszaverődés
A népszerűsített tulajdonságok – és a tulajdonságot népszerűsítő konstruktor-argumentumok – intuitív módon viselkednek, amikor a Reflection API-n keresztül befelé nézik őket. A reflexió a promotált tulajdonságokat vizsgálja transzláció utáni állapotukban, így azonosak egy kifejezetten deklarált tulajdonsággal.
Mind a ReflectionProperty
és ReflectionParameter
osztályoknak új isPromoted()
módszerek annak ellenőrzésére, hogy részt vettek-e a CPP-ben. Általában ezt azonban nem kell figyelembe venni, hacsak nem olyan eszközt írsz, amely meg akarja másolni a pontos forrásszerkezetet.
Lehetséges Gotchák
Nem deklarálhatja az osztályok és a népszerűsített tulajdonságok duplikált nevét. A következő példa futásidejű hibát eredményez:
class BlogPost { public string $Title; public function __construct(public string $Title) {} }
Ez azért van, mert a PHP nem igazán tesz különösebbet a népszerűsített tulajdonságok meghatározásával. Egyszerűen átfordítja a rövidített forráskódot a PHP 7.4 stílusba. Ez kettőt eredményezne public string $Title
vonalak, ami mindig is tilos volt.
Vannak más esetek, amikor a CPP hibát eredményezhet. A népszerűsített tulajdonságok az absztrakt osztályokban tilosak, bár jellemzőkben felhasználhatók. Nem tudja használni a callable
gépeljen velük, mert a tulajdonságdefiníciók nem támogatják. Végül, a variadikus paraméterek (pl public string ...$strings
), mert az ingatlan végül egy array
nak,-nek string
példányok, nem a string
maga.
Következtetés
A konstruktor tulajdonságai elősegítik az új értékobjektumok gyorsabb írását a kódalapba. Akár kétharmadával csökkentheti a vonalak számát! A CPP emellett segít a SZÁRÍTÁSBAN (Ne ismételje meg önmagát) azáltal, hogy elkerüli a PHP 7.4 által igényelt tipetípusok és tulajdonságnevek csúnya ismétlését.
A CPP elfogadása opcionális, és nem mindig lesz értelme a meglévő osztályoknak. A legalkalmasabb az egyszerű struktúraszerű osztályokhoz, ahol erőteljes gépelést szeretne biztosítani azoknak az adatoknak, amelyeket a kódbázisán keresztül továbbítanak.