Kiemelt kép

PHP 8 újdonságok VII - nullsafe operátor

A PHP fejlesztőcsapata 2020 végén kiadta a PHP következő főverzióját, a PHP 8.0-t. Ebben a posztsorozatban megnézzük, hogy milyen főbb változások és új nyelvi elemek érkeztek a PHP-ba. Az előző posztokban már megnéztük a kisebb-nagyobb változásokat (match, típusosság, attribútumok, új függvények, egyszerűsített konstruktor, named args), de még maradt egy nagyobb újdonság, a nullsafe operátor, amely új szintre emeli a nullkezelést a PHP-ban. Nézzük is, mi ez pontosan!

Szintaxis

Aki használ JavaScriptet, Kotlint vagy például C#-ot, annak már biztosan nem újdonság ez az operátor, a legtöbb nyelvben egy „?.” segítségével történik a nullable típusú változók meghívása, tehát egy kérdőjel kerül a pont elé. PHP-ban szintén ez a szintaxis valósult meg „?->” formájában.

Jelenleg a PHP már több megoldást is támogat a nullable változók kezelésére:

  • shorthand ternary operator (?:), amely segítségével alapértelmezett értéket tudunk definiálni, ha a feltétel kiértékelése false-t ad vissza,  PHP-ban ez a nullra is igaz, tehát az is false lesz
  • null coalescing operátor (??), amely kifejezetten nullable vagy nem létező változók kezelésére való, tehát például egy $obj->value ?? 1000 akkor is 1000 lesz, ha null a value, illetve akkor is, ha nincs ilyen tagváltozó.

Az új nullsafe operator bevezetésével egy fontos hiányosságot pótoltak a PHP fejlesztői, mégpedig a függvényhívás kezelését nullable változók esetén, tehát tudunk biztonságosan $maybeNullObject?->name() hívásokat csinálni, anélkül, hogy egy null pointer exceptiont dobjon a kód futás közben. Ilyen esetben a method meghívás csak akkor történik meg, ha a $maybeNullObject nem null, ellenkező esetben a PHP megszakítja a hívási láncot és visszatér nullal. 

Tudunk láncolva több ilyen hívást is csinálni, tehát például egy $order?->address?->street is tökéletesen működik. Ha null helyett default értéket akarunk biztosítani ilyen esetben, akkor $order?->address?->street ?? "Nincs utca megadva" kódsorral megtehetjük.

Előnyök

A nullsafe operátorral meg tudunk szabadulni a NullPointerExceptionöktől, ha tudjuk, hogy potenciálisan lehet null egy változó. Egy válós példa: ha vannak service classjaink, amelyekben logolni szeretnénk, de a class önmagában nem rendelkezik biztosan loggerrel, csak ha például a controllerünkben ezt setLoggerrel biztosítjuk, akkor tudunk $this->logger?->error() hívásokat használni. Ha csak hiba esetén logolunk, akkor ne feltétlenül dobjon hibát csak emiatt a kód (elfelejtettük átadni a loggert, de ez nem derül ki egyből), maximum nem lesz logunk az esetről, de a felhasználó megfelelően értesül róla, hogy probléma volt, nem egy irreleváns nullpointert kap helyette.

Továbbá, ha eddig egymásba ágyazott ifekekkel előztük meg a láncolt hívásoknál a nullpointer exception felbukkanását, akkor ez mostantól egy sorból megoldható.

Erre figyelni kell!
  • A nullsafe operátor nem kezeli a nem létező változókat, tehát ha a fenti példákból az $order?->address?->street esetében az $order eleve nem létezik, akkor hibát fogunk visszakapni.
  • Továbbá tömb indexek esetében szintén nem működik, tehát ha egy index nem létezik, amire mi alapból hivatkozni próbálunk, akkor az szintén hibára fut.
  • Nem támogatott az írási művelet. ($order?->address?->zipcode = 4000 nem lehetséges)

Források:
Nullsafe operator RFC
stitcher.io blog


Ha nem szeretnél lemaradni a hasonló posztokról, kövesd a blog Facebook oldalát!