Ragionando in PHP 7 Lezione 1: Tipizzazione scalare

Postato in PHP 7 | Programmazione PHP

PHP 5 ha introdotto a suo tempo la possibilità per lo sviluppatore di definire verbosamente i tipi di dato richiesti da una funzione. Questo impedisce l'esecuzione di funzioni o metodi richiamati con tipi di dati errati, come ad esempio passare un timestamp UNIX a un metodo che si aspetta un oggetto DateTime. In più, la tipizzazione rende anche chiaro agli altri sviluppatori come utilizzare la funzione in piena compatibilità. Per esempio, qui sotto, si analizzi la definizione delle due funzioni con e senza tipizzazione:

// Senza tipizzazione
function prossimoGiornoSettimana($data) { /*...*/ }
// Con tipizzazione (PHP5)
function prossimoGiornoSettimana(DateTime $data) { /*...*/ }

La tipizzazione era inizialmente limitata alle sole classi e interfacce, ma fu poi ampliata per consentire anche i tipi Array e Callable. PHP 7, invece, estende ulteriormente questo limite consentendo la tipizzazione scalare come int, float, string e bool:

// Tipizzazione scalare (PHP7)
// è possibile definire il tipo richiesto per il parametro $data come INT. E' chiaramente comprensibile allo sviluppatore che questa funzione accetta un timestamp.
function prossimoGiornoSettimana(int $data) { /*...*/ }

Controllo della tipizzazione

Il controllo di tipizzazione per i tipi scalari in PHP 7 funziona in modalità "Coercive", ovvero, nella stessa identica maniera con la quale le vecchie versioni di PHP effettuano il controllo di tipizzazione sulle funzioni built-in. Per meglio spiegare questo concetto, basta pensare alla situazione della funzione floor, che è così definita:

// definizione della funzione float built-in di PHP
float floor ( float $numero )

Quando si passa un parametro alla funzione float, PHP effettuerà una conversione "Coercive" del valore passato alla funzione, se questa è convertibile. Esiste una tabella di conversione per capire se un tipo di variabile può essere automaticamente convertito da PHP in modalità "Coercive":

Tipo di datointfloatstringboolobject
intsisi*si**sino
floatsisisi*sino
stringsisisisisi***
intsisisisino

*: Solo valori che non siano NaN e compresi tra PHP_INT_MIN e PHP_INT_MAX
**: solo se è una stringa numerica
***: solo se l'oggetto ha un metodo magico __toString()

PHP 7 introduce un nuovo metodo per il controllo della tipizzazione, chiamato "Strict", che permette allo sviluppatore di definire, all'inizio dello script, una particolare "frase" che, se presente, imporrà al compilatore di effettuare il controllo di tipizzazione in senso stretto, quindi senza interpolazione dei parametri "Coercive" come sopra spiegato. Attenzione: utilizzare il controllo di tipizzazione Strict farà in modo che anche eventuali funzioni built-in di PHP richiamate all'interno del file saranno sottoposte allo stesso identico trattamento di validazione.

La modalità Strict essenzialmente richiede che tutte le variabili passate alle funzioni tipizzate siano in regola con la definizione della funzione/metodo. In caso contrario, verrà lanciato un TypeError. Ad esempio, in modalità Strict, non è possibile utilizzare stringhe numeriche quando la tipizzazione richiede un float o un int (come invece in modalità Coercive è ammesso e funzionante):

<?php
declare(strict_types=1);
function ciao(string $nome): string {
   echo 'Ciao, ' . $name;
}
function somma(float $a, float $b): float {
   return $a + $b;
}
ciao('Alberto'); // Stampa: "Ciao, Alberto"
ciao(3); // genera un Fatal error: Uncaught TypeError: Argument 1 passed to ciao() must be of the type string, integer given
somma(2, 1); // ritorna "3" anche se i tipi passati sono int
somma(3.2, true); // genera un Fatal error: Uncaught TypeError: Argument 2 passed to somma() must be of the type float, bool given

Poiché la direttiva è impostata per ogni file, e ad inizio di ogni file, è possibile e ammesso combinare le modalità Strict e Coercive nell'applicazione. Ad esempio, se alcune parti della propria applicazione ( magari installate tramite Composer ) non richiedono tipizzazione stretta, mentre invece alcuni specifiche classi della propria applicazione la richiedono, tutta l'applicazione continuerà a funzionare, e il controllo di tipizzazione stretto verrà applicato solo ed esclusivamente sui file che ne fanno uso.

Compatibilità con versioni di PHP precedenti

Non è più possibile, con PHP 7, creare classi denominate int, float, string o bool in quanto queste andrebbero in conflitto con le nuove tipizzazioni di tipo scalare.

Questa era la prima lezione su PHP 7. Naviga nella categoria PHP7 di questo blog per scoprire le altre lezioni e le novità introdotte da PHP7