Dichiarazioni di tipo

Le dichiarazioni di tipo possono essere aggiunte agli argomenti delle funzioni, ai valori restituiti e, a partire da PHP 7.4.0, alle proprietà di classe. Assicurano che il valore sia del tipo specificato al momento della chiamata, altrimenti viene generato un TypeError.

Nota:

Quando si sovrascrive un metodo genitore, il metodo del figlio deve corrispondere a qualsiasi dichiarazione del tipo restituito sul genitore. Se il genitore non definisce un tipo restituito, allora il metodo figlio può farlo.

Tipi singoli

Tipo Descrizione Versione
Nome di classe/interfaccia Il valore deve essere un'instanceof della classe o dell'interfaccia data.  
self Il valore deve essere un'instanceof della stessa classe di quella su cui è definito il metodo. Può essere utilizzato solo nelle classi.  
array Il valore deve essere un array.  
callable Il valore deve essere una callable valida. Non può essere utilizzato come dichiarazione del tipo di proprietà della classe.  
bool Il valore deve essere un valore booleano.  
float Il valore deve essere un numero in virgola mobile.  
int Il valore deve essere un numero intero.  
string Il valore deve essere una string.  
iterable Il valore deve essere un array o un'instanceof Traversable. PHP 7.1.0
object Il valore deve essere un object. PHP 7.2.0
mixed Il valore può essere qualsiasi valore. PHP 8.0.0
Avviso

Gli alias per i tipi scalari di sopra non sono supportati. Vengono invece trattati come nomi di classi o interfacce. Ad esempio, usando boolean come dichiarazione di tipo richiederà che il valore sia un instanceof della classe o dell'interfaccia boolean, invece che di tipo bool:

<?php
    
function test(boolean $param) {}
    
test(true);
?>

Output of the above example in PHP 8:

Warning: "boolean" will be interpreted as a class name. Did you mean "bool"? Write "\boolean" to suppress this warning in /in/9YrUX on line 2

Fatal error: Uncaught TypeError: test(): Argument #1 ($param) must be of type boolean, bool given, called in - on line 3 and defined in -:2
Stack trace:
#0 -(3): test(true)
#1 {main}
  thrown in - on line 2

Esempi

Example #1 Dichiarazione di base del tipo classe

<?php
class {}
class 
extends {}

// Questa non estende C.
class {}

function 
f(C $c) {
    echo 
get_class($c)."\n";
}

f(new C);
f(new D);
f(new E);
?>

Output of the above example in PHP 8:

C
D

Fatal error: Uncaught TypeError: f(): Argument #1 ($c) must be of type C, E given, called in /in/gLonb on line 14 and defined in /in/gLonb:8
Stack trace:
#0 -(14): f(Object(E))
#1 {main}
  thrown in - on line 8

Example #2 Dichiarazione di base del tipo interfaccia

<?php
interface { public function f(); }
class 
implements { public function f() {} }

// Questa non implementa I.
class {}

function 
f(I $i) {
    echo 
get_class($i)."\n";
}

f(new C);
f(new E);
?>

Output of the above example in PHP 8:

C

Fatal error: Uncaught TypeError: f(): Argument #1 ($i) must be of type I, E given, called in - on line 13 and defined in -:8
Stack trace:
#0 -(13): f(Object(E))
#1 {main}
  thrown in - on line 8

Example #3 Dichiarazione di base del tipo restituito

<?php
function sum($a$b): float {
    return 
$a $b;
}

// Notare che verrà restituito un float.
var_dump(sum(12));
?>

Il precedente esempio visualizzerà:

float(3)

Example #4 Restituzione di un oggetto

<?php
class {}

function 
getC(): {
    return new 
C;
}

var_dump(getC());
?>

Il precedente esempio visualizzerà:

object(C)#1 (0) {
}

Tipo nullable

A partire da PHP 7.1.0, le dichiarazioni di tipo possono essere contrassegnate come nullable anteponendo al nome del tipo un punto interrogativo (?). Ciò significa che il valore può essere del tipo specificato o null.

Example #5 Dichiarazione del tipo di argomento nullable

<?php
class {}

function 
f(?C $c) {
    
var_dump($c);
}

f(new C);
f(null);
?>

Il precedente esempio visualizzerà:

object(C)#1 (0) {
}
NULL

Example #6 Dichiarazione del tipo restituito nullable

<?php
function get_item(): ?string {
    if (isset(
$_GET['item'])) {
        return 
$_GET['item'];
    } else {
        return 
null;
    }
}
?>

Nota:

Prima di PHP 7.1.0, era possibile ottenere argomenti nullable rendendo null il valore predefinito. Questo non è raccomandato in quanto si interrompe durante l'eredità.

Example #7 Vecchio modo per rendere gli argomenti nullable

<?php
class {}

function 
f(C $c null) {
    
var_dump($c);
}

f(new C);
f(null);
?>

Il precedente esempio visualizzerà:

object(C)#1 (0) {
}
NULL

Tipi union

Una dichiarazione di tipo union accetta valori di più tipi diversi, anziché uno solo. I tipi union vengono specificati utilizzando la sintassi T1|T2|.... I tipi union sono disponibili a partire da PHP 8.0.0.

Tipi union nullable

Il tipo null è supportato come parte delle union, in modo tale che T1|T2|null possa essere utilizzato per creare una union nullable. La notazione ?T esistente è considerata una scorciatoia per il caso comune di T|null.

Attenzione

null non può essere utilizzato come tipo autonomo.

pseudo-tipo false

Il tipo letterale false è supportato come parte delle union ed è incluso dato che per ragioni storiche molte funzioni interne restituiscono false invece di null per gli errori. Un classico esempio di tale funzione è strpos().

Attenzione

false non può essere utilizzato come tipo autonomo (incluso il tipo autonomo nullable). Pertanto, non sono consentiti tutti i valori false, false|null e false.

Attenzione

Il tipo letterale true non esiste.

Tipi duplicati e ridondanti

Per rilevare semplici bug nelle dichiarazioni di tipo union, i tipi ridondanti che possono essere rilevati senza eseguire il caricamento della classe risulteranno in un errore in fase di compilazione. Ciò comprende:

  • Ogni tipo risolto dal nome può verificarsi solo una volta. Tipi come int|string|INT generano un errore.
  • Se viene utilizzato bool, false non può essere utilizzato in aggiunta.
  • Se viene utilizzato object, i tipi di classe non possono essere utilizzati in aggiunta.
  • Se viene utilizzato iterabile, array e Traversable non possono essere utilizzati in aggiunta.

Nota: Ciò non garantisce che il tipo sia “minimo”, poiché ciò richiederebbe il caricamento di tutti i tipi di classe utilizzati.

Ad esempio, se A e B sono alias di classe, A|B rimane un tipo di union legale, anche se potrebbe essere ridotto a A o B. Allo stesso modo, se la classe B extends A {}, anche A|B è un tipo di union legale, anche se potrebbe essere ridotta solo a A.

<?php
function foo(): int|INT {} // Non consentito
function foo(): bool|false {} // Non consentito

use as B;
function 
foo(): A|{} // Non consentito ("use" fa parte della risoluzione dei nomi)

class_alias('X''Y');
function 
foo(): X|{} // Consentito (la ridondanza è nota solo in fase di esecuzione)
?>

Tipi di solo ritorno

void

void è un tipo di ritorno che indica che la funzione non restituisce un valore. Pertanto non può essere parte di una dichiarazione di tipo union. Disponibile da PHP 7.1.0.

static

Il valore deve essere un'instanceof della stessa classe di quella in cui è chiamato il metodo. Disponibile da PHP 8.0.0.

Tipizzazione strict

Per impostazione predefinita, PHP costringerà i valori del tipo sbagliato nella dichiarazione del tipo scalare previsto, se possibile. Ad esempio, una funzione a cui viene assegnato un int per un parametro che prevede una string otterrà una variabile di tipo string.

È possibile abilitare la modalità strict per file. In modalità strict, sarà accettato solo un valore corrispondente esattamente alla dichiarazione del tipo, altrimenti verrà lanciato un TypeError. L'unica eccezione a questa regola è che un valore int passerà una dichiarazione di tipo float.

Avviso

Le chiamate di funzione dall'interno delle funzioni interne non saranno influenzate dalla dichiarazione strict_types.

Per abilitare la modalità rigorosa, il declare viene utilizzato con la dichiarazione strict_types:

Nota:

La tipizzazione strict si applica alle chiamate di funzione effettuate all'interno del file con la tipizzazione strict abilitata, non alle funzioni dichiarate all'interno di quel file. Se un file senza la tipizzazione strict abilitata effettua una chiamata a una funzione che è stata definita in un file con la tipizzazione strict, la preferenza del chiamante (tipizzazione coercitiva) verrà rispettata e il valore verrà forzato.

Nota:

La tipizzazione strict è definita solo per le dichiarazioni di tipo scalare.

Example #8 Tipizzazione strict per i valori degli argomenti

<?php
declare(strict_types=1);

function 
sum(int $aint $b) {
    return 
$a $b;
}

var_dump(sum(12));
var_dump(sum(1.52.5));
?>

Output of the above example in PHP 8:

int(3)

Fatal error: Uncaught TypeError: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 9 and defined in -:4
Stack trace:
#0 -(9): sum(1.5, 2.5)
#1 {main}
  thrown in - on line 4

Example #9 Tipizzazione coercitiva per i valori degli argomenti

<?php
function sum(int $aint $b) {
    return 
$a $b;
}

var_dump(sum(12));

// Questi verranno convertiti in numeri interi: nota l'output qui sotto!
var_dump(sum(1.52.5));
?>

Il precedente esempio visualizzerà:

int(3)
int(3)

Example #10 Tipizzazione strict per i valori di ritorno

<?php
declare(strict_types=1);

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

var_dump(sum(12));
var_dump(sum(12.5));
?>

Il precedente esempio visualizzerà:

int(3)

Fatal error: Uncaught TypeError: sum(): Return value must be of type int, float returned in -:5
Stack trace:
#0 -(9): sum(1, 2.5)
#1 {main}
  thrown in - on line 5

Tipizzazione coercitiva con tipi union

Quando strict_types non è abilitato, le dichiarazioni di tipo scalare sono soggette a limitate coercizioni di tipo implicito. Se il tipo esatto del valore non fa parte della union, il tipo di destinazione viene scelto nel seguente ordine di preferenza:

  1. int
  2. float
  3. string
  4. bool
Se il tipo esiste nella union e il valore può essere forzato al tipo sotto la semantica di controllo del tipo esistente di PHP, viene scelto il tipo. Altrimenti viene provato il tipo successivo.

Attenzione

In via eccezionale, se il valore è una stringa e sia int che float fanno parte della union, il tipo preferito è determinato dalla semantica “stringa numerica” esistente. Ad esempio, per "42" viene scelto int, mentre per "42.0" viene scelto float.

Nota:

I tipi che non fanno parte dell'elenco di preferenze di cui sopra non sono obiettivi ammissibili per la coercizione implicita. In particolare non si verificano coercizioni implicite ai tipi null e false.

Example #11 Esempio di tipi che vengono forzati in un tipo parte della union

<?php
// int|string
42    --> 42          // tipo esatto
"42"  --> "42"        // tipo esatto
new ObjectWithToString --> "Risultato di __toString()"
                      
// oggetto mai compatibile con int, ripiega su string
42.0  --> 42          // float compatibile con int
42.1  --> 42          // float compatibile con int
1e100 --> "1.0E+100"  // float troppo grande per il tipo int, ripiega su string
INF   --> "INF"       // float troppo grande per il tipo int, ripiega su string
true  --> 1           // bool compatibile con int
[]    --> TypeError   // array non compatibile con int o string

// int|float|bool
"45"    --> 45        // stringa numerica intera
"45.0"  --> 45.0      // stringa numerica float

"45X"   --> true      // non una stringa numerica, ripiega su bool
""      --> false     // non una stringa numerica, ripiega su bool
"X"     --> true      // non una stringa numerica, ripiega su bool
[]      --> TypeError // array non compatibile con int, float o bool
?>

Misc

Example #12 Parametri passati per referenza Tipizzati

I tipi dichiarati di parametri di referenza vengono controllati all'immissione della funzione, ma non quando la funzione ritorna, quindi dopo che la funzione ritorna, il tipo dell'argomento potrebbe essere cambiato.

<?php
function array_baz(array &$param)
{
    
$param 1;
}
$var = [];
array_baz($var);
var_dump($var);
array_baz($var);
?>

Output of the above example in PHP 8:

int(1)

Fatal error: Uncaught TypeError: array_baz(): Argument #1 ($param) must be of type array, int given, called in - on line 9 and defined in -:2
Stack trace:
#0 -(9): array_baz(1)
#1 {main}
  thrown in - on line 2

Example #13 Cattura TypeError

<?php
declare(strict_types=1);

function 
sum(int $aint $b) {
    return 
$a $b;
}

try {
    
var_dump(sum(12));
    
var_dump(sum(1.52.5));
} catch (
TypeError $e) {
    echo 
'Error: '$e->getMessage();
}
?>

Output of the above example in PHP 8:

int(3)
Error: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 10
add a note add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top