L’RFC delle Typed Properties è stato unito al ramo master e sarà disponibile nella versione PHP 7.4!
L’arrivo di questa novità non è certo un game-changer, ma sicuramente una novità (che avvicina PHP ad altri linguaggi) ben gradita, per scrivere un codice più netto e pulito. In precedenza, come prassi, avremmo utilizzato le annotazioni per definire il tipo di una proprietà:
class ClasseQualsiasi { /** * @var int */ private $count; }
Abbiamo, insomma, utilizzato dei commenti […] ed ora potremmo utilizzare del codice vero.
Vediamo ora come dichiarare esplicitamente che $count è di tipo int in PHP 7.4:
class ClasseQualsiasi { private int $count; }
Molto meglio, vero?
Anche i metodi setters e getters potrebbero essere aggirati (non scrivendoli affatto), semplicemente affidando il controllo del tipo alla dichiarazione della proprietà, passando così da questo:
class ClasseQualsiasi { /** * @var int */ private $count; function setCount(int $count): int { $this->count=$count; } }
a questo:
class ClasseQualsiasi { private int $count; }
senza perdere la sicurezza del controllo del tipo int. Non male.
Tipi ammessi
I types ammessi sono:
- bool, int, float, string, array, object
- iterable
- self, parent
- un nome di una classe o interface
- ?type, dove “type” è uno qualsiasi dei precedenti
Fate attenzione al tipo parent, perché potrebbe.. non esserci un parent.
Ereditarietà
Quando ereditiamo una classe, le sue typed properties marcate come public non potranno essere cambiate. Quelle private, naturalmente, possono essere scelte arbitrariamente.
class Utente { private bool $attivo; private int $eta; public string $nome; } class SuperUtente extends Utente { private int $attivo; // No private ?int $eta; // No public string $nome; // Si }
Il cambio di typing da int a ?int implica che la proprietà possa restituire null e quindi è invalida.
Valori di default
I valori di default devono corrispondere al tipo dichiarato, con l’unica eccezione del tipo float che accetta anche valori interi. Il valore null può essere impostato come default soltanto se la proprietà è di tipo nullable.
class Test { // Valori corretti public bool $a = true; public int $b = 42; public float $c = 42.42; public float $d = 42; // Eccezione public string $e = "str"; public array $f = [1, 2, 3]; public iterable $g = [1, 2, 3]; public ?int $h = null; public ?object $i = null; public ?Test $j = null; // Errore! public bool $m = 1; public int $n = null; public Test $o = null; }
Prima che però ci buttiamo a capofitto nel ractoring di tutto il nostro codice, teniamo in considerazione il possibile utilizzo delle interfaces.
Lo possiamo utilizzare nelle interfaces?
In breve, no.
Non appena introdurremo il typing delle proprietà, non potremmo più usare un’astrazione. Senza typed properties, ci troveremmo a riscrivere i metodi getters and setters per rafforzare il controllo sul tipo. Non potremmo, cioè fare questo:
interface ProductInterface { public int $prezzo; public string $descrizione; } class Product implements ProductInterface { public int $prezzo; public string $descrizione; }
Per approfondire tutte le novità, seguite il link ufficiale (in inglese)
Vi ricordo che l’uscita di PHP 7.4 è programmata per novembre 2019.