Ausblick auf PHP 8: Teil 4

PHP 8.0-Features im Fokus: Nullsafe Operator
Keine Kommentare

Das Release von PHP 8 steht kurz bevor und mit ihm eine Reihe von Verbesserungen, neuen Funktionen und die generelle Überarbeitung, um die weit verbreitete serverseitige Websprache noch besser zu machen. In dieser Serie wollen wir darauf eingehen, was Sie über PHP 8 wissen sollten.

Der Countdown zum großen Release von PHP 8 ist bereits angebrochen. Die lang erwartete neue Version enthält eine ganze Reihe von neuen Funktionen und Verbesserungen, die den Entwicklern das Leben leichter machen sollen. In dieser Serie werfen wir einen Blick auf diese Neuerungen und was sie für die Nutzer bedeuten. Bereits letzte Woche haben wir Weak Maps verwendet, um einen bestimmten Grenzfall zu lösen. In diesem Artikel vereinfachen wir den häufigsten und nervigsten: Den des „Nichtvorhandenseins“.

Sind wir mal ehrlich, Null-Values sind nervig. Sie wurden schon als „Millionen-Dollar-Fehler“ bezeichnet, trotzdem müssen Programmierer in den meisten Sprachen mit ihnen umzugehen wissen. (Mit Ausnahme von denen, die mit Rust arbeiten.) Sie sind besonders dann nervig, wenn man eine Variable hat, die ein Objekt oder Null sein kann. Falls es sich um ein Objekt handelt, kennt man vermutlich seinen Typ und weiß, was zu tun ist. Falls die Variable aber Null ist, kann man nicht viel damit anfangen. Standardmäßig öffnet man in dieser Situation einen Branch, indem man eine Bedingung abfragt, namentlich das if null-Pattern.

<?php
$user = get_user($id);
if (!is_null($user)) {
    $address = $user->getAddress();
    if (!is_null($address)) {
        $state = $address->state;
        If (!is_null($state)) {
            // And so on.
        }
    }
}

Das ist natürlich unschön und schwer zu lesen, aber notwendig, wenn man den Aufruf eines Call to a member function on null-Fehlers umgehen möchte.

In einer idealen Welt könnten wir unseren Code so strukturieren, dass Null unmöglich ist. Leider leben wir nicht in einer solchen idealen Welt. Insbesondere, wenn wir mit dem Code eines anderen arbeiten müssen. Aus diesem Grund gibt es in einer Reihe von Sprachen das, was wir einen „Nullsafe Operator“ nennen. Mit der Version 8.0 gehört PHP zu diesen Sprachen. Der Nullsafe Operator ist ein Modifier beim Objektzugriff, seien es Properties oder Method Calls. Wenn einem von diesen ein ? vorangestellt wird, hat dies den gleichen Effekt, als ob man den Zugriff in einen if (!is_null))-Check einpackt. Das obige Beispiel ändert sich folgendermaßen:

<?php
$state = get_user($id)?->getAddress()?->state;

In diesem Beispiel ist der von get_user ausgeworfene Wert entweder ein User-Objekt oder Null. Der Wert, der von User::getAdress() ausgeworfen wird, ist entweder ein Address-Objekt oder Null. Falls get_user() Null ausgibt, wird dies vom ? erfasst und als null zurückgegeben, wobei der gesamte Rest der Code-Zeile ignoriert wird. Dasselbe passiert für getAddress(). Am Ende ist $state entweder ein valider State Value, der aus dem state Property der Adresse gezogen wurde oder er ist Null.

Der Nullsafe Operator umgeht beim ersten Auftreten einer Null Value den Rest der Code-Zeile. Das bedeutet, dass sogar dynamische oder fehlerhafte Calls im späteren Prozess nicht auftreten werden. Ein Beispiel:

<?php

$bestSaleItem = $catalog?->getProducts(get_seasonal_type())?->mostPopular(10)[5];

Falls $catalog Null ist, wird get_seasonable_type() gar nicht erst aufgerufen. Die gesamte Kette stoppt sobald erkannt wurde, dass $catalog Null ist und setzt $bestSaleItem auf Null. Ähnlich funktioniert dies, falls getProduct() Null auswirft – dann wird mostPopular() niemals aufgerufen. Dies alles ist auf Arrays nicht anwendbar. Falls mostPopular() dennoch aufgerufen wird und Null ausgibt, erhält man immer noch den Fehler: Trying to access array offset on value of type null.

Es gibt natürlich ein paar Grenzen für den Nullsafe Operator. Er funktioniert nur, um Properties oder Methoden auszulesen und nicht, um Values zuzuschreiben. Er kümmert sich auch nicht um Referenzierungen, da diese reale Values benötigen. (Dies ist auch bei anderen Sprache, die einen Nullsafe Operator besitzen, der Fall.) Der Nullsafe Operator bietet auch keinen Hinweis darauf, welcher Schritt in der Kette eine Null ausgeworfen hat. Falls $bestSaleItem Null ist, könnte es daran liegen, dass $catalog Null ist. Oder aber, weil getProducts() oder mostPopular() eine Null ausgegeben haben. Es gibt keine Möglichkeit, dies zu bestimmen. Für manche Fälle ist das in Ordnung. Falls man aber den Unterschied bestimmen muss, ist der Nullsafe keine Hilfe. Dann braucht man tatsächlich einen Either Monad, aber das ist ein Thema für ein anderes Mal…

Wie dem auch sei, Nullsafe kann die Größe von Boilerplate Code reduzieren, der durch objektorientierte Methodchains schwebt. Wir danken Ilija Tovilo für diesen RFC.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Abonnieren
Benachrichtige mich bei
guest
0 Comments
Inline Feedbacks
View all comments
X
- Gib Deinen Standort ein -
- or -