I tipi in PHP 8: dichiararli e sfruttarli
Type declarations, strict_types, union, intersection, nullable, mixed, never e property promotion
PHP è a tipizzazione dinamica: una variabile può contenere oggi un numero e domani una stringa. Comodo, ma pericoloso. Da PHP 7, e sempre di più con PHP 8, puoi dichiarare i tipi: dici a PHP «questo parametro deve essere un intero» e lui lo fa rispettare al posto tuo. Se etichettiamo i barattoli che riponiamo in cucina: «farina», «zucchero», «sale», etc., eviteremo che mettiamo l'ingrediente sbagliato nel barattolo.
1. Type declarations: l'etichetta sul dato
Puoi dichiarare il tipo di tre cose: i parametri di una funzione, il valore di ritorno (il return type) e le proprietà di una classe. Se qualcuno passa un tipo sbagliato, PHP lancia un TypeError.
function saluta(string $nome): string { return "Ciao, $nome"; }
Qui string $nome impone che il parametro sia una stringa; la : string dopo le parentesi impone che il valore restituito sia una stringa.
Fonte: PHP Manual: «Type declarations» (php.net).
2. strict_types: controlli rigidi o indulgenti?
Di default PHP è indulgente («coercive»): se una funzione vuole un int e tu passi la stringa "42", PHP la converte in 42 senza protestare. Comodo, ma può nascondere bug veri.
Mettendo declare(strict_types=1); come primissima riga del file, attivi la modalità rigida: PHP pretende il tipo esatto, altrimenti TypeError.
declare(strict_types=1); // deve essere la prima istruzione del file
function somma(int $a, int $b): int {
return $a + $b;
}
somma(1, 2); // OK -> 3
somma("1", 2); // TypeError! (senza strict darebbe 3)
Vale file per file, e l'unica eccezione è che un int può passare dove è richiesto un float.
Fonte: PHP Manual: «Type declarations: strict typing» (php.net).
3. Nullable, union e mixed: più tipi ammessi
A volte un valore può essere legittimamente di più tipi. PHP offre tre strumenti:
- ?tipo nullable: quel tipo oppure null. ?string è la scorciatoia di string|null.
- tipo|tipo union (PHP 8.0): uno tra più tipi. int|string = «o un intero o una stringa».
- mixed (PHP 8.0): qualsiasi tipo. È l'opposto di essere precisi: usalo solo quando davvero ogni valore va bene.
function trovaUtente(int $id): ?User { /* ... */ } // un User, oppure null
function formatta(int|string $val): string { /* ... */ }
function registra(mixed $qualsiasi): void { /* ... */ }
Il nullable è un campo del modulo che può restare in bianco; l'union è un distributore che accetta «monete O banconote»; mixed è una scatola dove butti dentro qualunque cosa: comoda, ma poi non sai bene cosa ci trovi.
Fonte: PHP Manual: «Type declarations» (union, nullable, mixed); RFC «mixed type» (php.net / wiki.php.net).
4. Intersection e never (PHP 8.1): i più avanzati
L'intersection type (A&B) è l'opposto dell'union: il valore deve soddisfare tutti i tipi indicati contemporaneamente (solo classi e interfacce). Union = «O questo O quello»; intersection = «SIA questo SIA quello».
// $v deve essere sia iterabile (Iterator) sia contabile (Countable)
function elabora(Iterator&Countable $v): void { /* ... */ }
L'intersection è come cercare una persona che sia SIA medico SIA pilota: non basta una sola qualifica, deve averle entrambe. L'union invece si accontenta di una delle due.
Il tipo di ritorno never (PHP 8.1) indica una funzione che non ritorna mai: lancia sempre un'eccezione oppure chiama exit() / die().
function erroreFatale(string $msg): never {
throw new RuntimeException($msg);
}
Fonte: PHP Manual: «Type declarations» e RFC «pure-intersection-types», «never» (php.net / wiki.php.net).
5. Constructor property promotion (PHP 8.0): meno codice ripetuto
Prima, per salvare i parametri del costruttore nelle proprietà, dovevi scrivere ogni nome tre volte: dichiarazione, parametro e assegnazione. Da PHP 8 basta mettere la parola di visibilità (public/private/protected) davanti al parametro: PHP crea e assegna la proprietà da solo.
// PRIMA (PHP 7)
class Punto {
public float $x;
public float $y;
public function __construct(float $x, float $y) {
$this->x = $x;
$this->y = $y;
}
}
// DOPO (PHP 8): property promotion: stesso risultato
class Punto {
public function __construct(
public float $x = 0.0,
public float $y = 0.0,
) {}
}
Fonte: PHP Manual: «Constructor Promotion» / RFC «constructor_promotion» (php.net / wiki.php.net).
In sintesi
| Strumento | Cosa fa | Esempio |
|---|---|---|
| Type declaration | Dichiara il tipo di parametri, ritorni, proprietà | int $x : string |
| strict_types=1 | Controlli rigidi, niente conversioni automatiche | declare(strict_types=1); |
| Nullable ?T | Quel tipo, oppure null | ?string |
| Union | | Uno tra più tipi | int|string |
| mixed | Qualsiasi tipo | mixed $x |
| Intersection & | Tutti i tipi insieme (classi/interfacce) | Iterator&Countable |
| never | La funzione non ritorna mai | : never |
| Property promotion | Dichiara e assegna nel costruttore | public float $x |
I tipi non sono burocrazia: sono un contratto che PHP fa rispettare al posto tuo. Più i tuoi tipi sono chiari, meno bug ti sfuggono, e con strict_types attivo, PHP diventa il tuo primo revisore.
Per approfondire
- Readonly properties e readonly classes in PHP 8.1/8.2: readonly si combina con la constructor property promotion vista qui.
- OOP PHP: classi, oggetti, costruttore, distruttore: classi, oggetti e costruttore: le basi su cui si appoggiano i tipi.
Commenti (0)
Registrati per commentare, fare domande e proporre l'argomento della prossima pillola (oppure accedi se hai già un account).
Nessun commento. Sii il primo a scrivere qualcosa.