Dichiarazione dei tipi in ingresso e uscita delle funzioni

PHP 7: dichiarazione dei tipi in ingresso e uscita delle funzioni

Una delle novità più importanti di PHP 7 è stata l'introduzione della dichiarazione dei tipi in ingresso e in uscita delle funzioni. In particolare a partire da PHP 7, per i parametri in ingresso è possibile dichiarare valori di tipo scalare: int, float, string e bool.

Questi vanno ad aggiungersi al tipo class e al tipo array, disponibili rispettivamente da PHP 5.0 e PHP 5.1 e al tipo object che sarà aggiunto successivamente in PHP 7.2.

Oltre ai tipi scalari in ingresso, PHP 7 ha introdotto la possibilità di dichiarare anche il tipo di dato per i valori restituiti dalle funzioni.

La dichiarazione dei tipi (o type hinting) delle funzioni "forza" il programmatore a passare come parametri solamente valori di un determinato tipo. Questo consente di scrivere codice più robusto e facile da leggere.

Ma vediamo i benefici apportati dal type hinting attraverso alcuni esempi di codice e come poter sfruttare questa caratteristica del linguaggio.

Cos'è il type hinting

Poiché PHP è un linguaggio a tipizzazione debole, non è necessario specificare un tipo di dati per le variabili o per i parametri delle funzioni.

Tuttavia dalla versione 5, il linguaggio consente di specificare il tipo di dati che viene passato come parametro delle funzioni. Questa funzionalità è chiamata type hinting o dichiarazione del tipo di dati. Se ad esempio viene passato un valore con un tipo di dato diverso da quello definito nella dichiarazione della funzione, viene generato un errore fatale.

Prima di dare uno sguardo agli esempi pratici vediamo alcuni dei vantaggi apportati dal type hinting.

Vantaggi

Il type hinting porta con sè diversi benefici tra cui:

  • Evita la scrittura di codice aggiuntivo per identificare il tipo di dati
  • Se si lavora in team, si riduce la possibilità che altri sviluppatori utilizzino la funzione in modo sbagliato.
  • Quando si lavora con un IDE vengono dati suggerimenti sul tipo di dato accettato dalle funzioni, evitando così di commettere errori.

Vediamo come sfruttare questa funzionalità introducendo un nuovo costrutto del linguaggio.

Costrutto declare

Il costrutto declare viene utilizzato per modificare il comportamento di alcune direttive del linguaggio in fase di esecuzione del codice. La sintassi di declare è simile a quella di altre strutture di controllo

declare (directive)

Tra le direttive che è possibile impostare c'è strict_types, che in pratica fa si che venga sollevata un eccezione (un errore) qualora non vengano rispettati i tipi dichiarati in ingresso e/o in uscita delle funzioni.

Per attivare il controllo è sufficiente inserire la seguente riga di codice all'inizio di ogni script

declare(strict_types=1);

Per disabilitare il controllo sui tipi è sufficiente rimuovere la riga precedente oppure passare come valore 0 anziché 1.

Tipi in ingresso

Per specificare il tipo in ingresso di una funzione, è necessario aggiungere il nome del tipo prima del nome del parametro come mostra il seguente esempio

<?php
declare(strict_types=1); // attiviamo il controllo sui tipi

function printHello(string $name) // la funzione accetta solo valori di tipo string
{
    echo "Hello $name";
}

printHello('Flavio');

La funzione printHello() stampa a video una stringa contenente il nome passato come parametro. In questo caso abbiamo indicato string come tipo di dato del parametro $name.

Vediamo cosa succede se passiamo un valore di tipo int

<?php
declare(strict_types=1);

function printHello(string $name)
{
    echo "Hello $name";
}

printHello(4); // genera un errore

Se eseguiamo il codice precedente otteniamo il seguente errore

PHP Fatal error:  Uncaught TypeError: Argument 1 passed to printHello() must be of the type string, int given...

L'interprete PHP solleva un eccezione di tipo TypeError poiché non stiamo passando il tipo di dato corretto alla funzione, la quale si aspetta una stringa piuttosto che un intero.

Nota: se impostiamo lo strict_types a 0, il programma viene correttamente eseguito senza generare errori.

Tipi in uscita

PHP 7 offre anche la possibilità di specificare il tipo del valore ritornato da una funzione. Per specificare il tipo in uscita delle funzioni è necessario aggiungere il carattere dei due punti : dopo la parentesi di chiusura della funzione, seguito dal nome del tipo che vogliamo restituire

Vediamo un esempio di utilizzo

<?php
declare(strict_types=1);

function sum(int $a, int $b): int
{
    return $a + $b;
}

echo sum(4, 9);

La funzione deve restituire un valore di tipo int, altrimenti viene generato un errore. Infatti se modifichiamo il codice precedente in questo modo

<?php
declare(strict_types=1);

function sum(int $a, int $b): int
{
    return 4.4 + $b;
}

echo sum(4, 9);

e lo eseguiamo, otteniamo il seguente errore

PHP Fatal error: Uncaught TypeError: Return value of sum() must be of the type int, float returned...

poiché il valore restituito dalla funzione sum() sarà di tipo float.

Nota: a partire da PHP 7.1 è possibile utilizzare come risultato di una funzione il valore void, che indica che la funzione non restituisce alcun valore. Se la funzione restituisce un valore viene generato un errore.

<?php
declare(strict_types=1);

function printHello(string $name): void
{
    return "Hello $name";
}

printHello('Flavio');

Il codice genera il seguente errore poiché stiamo ritornando un valore nonostante il tipo in uscita impostato a void

PHP Fatal error: A void function must not return a value...

Guida successiva: Funzioni per gestire array