L’introduzione dell’operatore null coalescing con PHP 7 è stato un buon passo avanti per la pulizia del codice, ma non ha portato miglioramenti per quanto riguarda i metodi di classe, perché su di essi non era possibile utilizzarlo. Per aggirare il problema eravamo costretti ad assegnare il risultato del metodo e poi controllarlo prima di utilizzarlo, in questo modo:
$data = $intervento->getStartDate(); $data_string = $data ? $intervento->asDateTimeString() : null;
PHP 8 ha visto l’introduzione del null-safe operator, considerabile come una funzionalità simile al null-coalescing ma applicata appunto a questo tipo di operazioni.
$country = null;
if ($session !== null) {
$user = $session->user;
if ($user !== null) {
$address = $user->getAddress();
if ($address !== null) {
$country = $address->country;
}
}
}PHP 8 ci permette di scrivere questo blocco di controllo IF in questo modo:
$country = $session?->user?->getAddress()?->country;
Vediamolo in dettaglio.
L’operatore nullsafe nel dettaglio
Siccome potrebbe confondere, la prima domanda alla quale risponderemo è: qual è la differenza tra questo nuovo operatore e il null-coalescing, che continua ovviamente ad esistere?
Partiamo da questo esempio:
class Ordine
{
public ?Fattura $fattura = null;
}
$ordine = new Ordine();In questa situazione, la proprietà $fattura della classe Ordine è collegata ad un istanza della classe Fattura, che può esserci o non esserci (un ordine può avere una fattura collegata, o magari ancora no). Difatti, utilizziamo la notazione ? davanti al tipo di dato al momento della dichiarazione. Come sappiamo, questo ci dice che $fattura può essere soltanto di tipo Fattura o di tipo null.
Se accedessimo direttamente ad una proprietà di $fattura, utilizzando ad esempio $ordine->fattura->numero, otterremmo un errore, come in questo caso:
echo $ordine->fattura->numero; // errore, $order->fattura è null, non possiamo accedere alla proprietà "numero"
Con il null-safe operator potremmo scrivere, senza incorrere in errore:
echo $order->fattura?->numero;
Abbiamo visto come utilizzare il null-safe operator sulle proprietà, possiamo utilizzarlo naturalmente anche sui metodi:
class Ordine
{
public static function getReferral(): ?User
{
// ...
}
}Possiamo utilizzare l’operatore per assicurarci che il risultato di getReferral() sia null:
echo Ordine::getReferral()?->cognome;
Analogamente a quanto visto nel caso precedente, il metodo getReferral() potrebbe restituire null oppure una istanza di Utente. Se provassimo quindi ad accedere alla proprietà cognome di Utente potremmo incorrere in errore:
echo (Ordine::getReferral()->cognome ?? 'nessun cognome'); Fatal error: Uncaught Error: Call to a member function getReferral() on null
Operatori annidati
È possibile utilizzare operatori multipli, come in questo caso:
$classe?->metodo1()?->metodo2()?->metodo3();
In questo caso metodo1() verrà chiamato solo se $classe non è null, metodo2() solo se metodo1() non è null e così via.
Per concludere, questo nuovo operatore introdotto in PHP 8 era un pezzo decisamente mancante, e semplificherà sicuramente la scrittura e la leggibilità del codice.