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

TypeDescriptionVersionNome 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 in cui viene utilizzata la dichiarazione del tipo. Può essere utilizzato solo nelle classi. parent Il valore deve essere un'Instanceof del genitore della classe in cui viene utilizzata la dichiarazione del tipo. Può essere utilizzato solo nelle classi. array Il valore deve essere un . arraycallable Il valore deve essere una valida. Non può essere utilizzato come dichiarazione del tipo di proprietà della classe. callablebool 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 . stringiterable Il valore deve essere un o un'Instanceof . arrayTraversablePHP 7.1.0object Il valore deve essere un . objectPHP 7.2.0mixed Il valore può essere qualsiasi valore. PHP 8.0.0
Attenzione: 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); ?> Example outputs 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
mixed

mixed è equivalente al tipo union objectresourcearraystring intfloatboolnull . Disponibile a partire da PHP 8.0.0.

Esempi

Dichiarazione di base del tipo classe



<?php
class C {}
class D extends C {}

// Questa non estende C.
class E {}

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

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

    
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

Dichiarazione di base del tipo interfaccia



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

// Questa non implementa I.
class E {}

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

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

    
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

Dichiarazione di base del tipo restituito



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

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

    
float(3)

Restituzione di un oggetto



<?php
class C {}

function getC(): C {
    return new C;
}

var_dump(getC());
?>

    
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.

Dichiarazione del tipo di argomento nullable <?php class C {} function f(?C $c) { var_dump($c); } f(new C); f(null); ?> Example outputs object(C)#1 (0) { } NULL Dichiarazione del tipo restituito nullable <?php function get_item(): ?string { if (isset($_GET['item'])) { return $_GET['item']; } else { return null; } } ?>

Nota: È possibile ottenere argomenti nullable rendendo null il valore predefinito. Questo non è raccomandato in quanto si interrompe durante l'eredità. Vecchio modo per rendere gli argomenti nullable <?php class C {} function f(C $c = null) { var_dump($c); } f(new C); f(null); ?> Example outputs object(C)#1 (0) { } NULL

Tipi compositi

È possibile combinare tipi semplici in tipi compositi. PHP consente di combinare i tipi nei seguenti modi:

  • Union di tipi semplici. A partire da PHP 8.0.0.
  • Intersezione di tipi di classi (interfacce e nomi di classi). A partire da PHP 8.1.0.

Non è possibile combinare i tipi di intersezione con i tipi union.

Tipi union

Una dichiarazione di tipo union accetta valori di più tipi semplici 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.

null non può essere utilizzato come tipo autonomo.

Lo pseudotipo false

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

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

Il tipo letterale true non esiste.

Tipi intersezione

Una dichiarazione di tipo intersezione accetta valori che soddisfano più dichiarazioni di tipo classe, anziché una singola. I tipi intersezione sono specificati utilizzando la sintassi T1AmpT2Amp.... I tipi intersezione sono disponibili a partire da PHP 8.1.0.

Tipi duplicati e ridondanti

Per rilevare semplici bug nelle dichiarazioni di tipo composito, 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 o CountableAmpTraversableAmpCOUNTABLE generano un errore. L'utilizzo di mixed genera un errore. Per i tipi union: Se viene usato bool, false non può essere utilizzato in aggiunta. Se viene usato object, i tipi di classe non possono essere utilizzati in aggiunta. Se viene usato iterable, array e Traversable non possono essere utilizzati in aggiunta. Per i tipi intersezione: L'utilizzo di un tipo che non è un tipo di classe genera un errore. L'utilizzo di self, parent o static genera un errore.

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 function foo(): int&Traversable {} // Non consentito function foo(): self&Traversable {} // Non consentito use A as B; function foo(): A|B {} // Non consentito ("use" fa parte della risoluzione dei nomi) function foo(): A&B {} // Non consentito ("use" fa parte della risoluzione dei nomi) class_alias('X', 'Y'); function foo(): X|Y {} // Consentito (la ridondanza è nota solo in fase di esecuzione) function foo(): X&Y {} // 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.

Nota: Il ritorno per riferimento da una funzione void è deprecato a partire da PHP 8.1.0, perché tale funzione è contraddittoria. In precedenza, emetteva già il seguente E_NOTICE quando chiamata: Only variable references should be returned by reference. <?php function &test(): void {} ?>
never

never è un tipo di ritorno che indica che la funzione non ha un ritorno. Ciò significa che chiama exit, genera un'eccezione o è un ciclo infinito. Pertanto non può essere parte di una dichiarazione di tipo union. Disponibile a partire da PHP 8.1.0.

never è, nel gergo della teoria dei tipi, il tipo inferiore. Significa che è il sottotipo di ogni altro tipo e può sostituire qualsiasi altro tipo di ritorno durante l'ereditarietà.

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.

Attenzione: 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.

Tipizzazione strict per i valori degli argomenti



<?php
declare(strict_types=1);

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

var_dump(sum(1, 2));
var_dump(sum(1.5, 2.5));
?>

   
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

Tipizzazione coercitiva per i valori degli argomenti



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

var_dump(sum(1, 2));

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

   
int(3) int(3)

Tipizzazione strict per i valori di ritorno



<?php
declare(strict_types=1);

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

var_dump(sum(1, 2));
var_dump(sum(1, 2.5));
?>

   
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: int float string 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.

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.

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

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);
?>

    
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

Cattura



<?php
declare(strict_types=1);

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

try {
    var_dump(sum(1, 2));
    var_dump(sum(1.5, 2.5));
} catch (TypeError $e) {
    echo 'Error: ', $e->getMessage();
}
?>

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