Situazione attuale: PHP2Shell. Due vulnerabilità critiche di PHP (CVSS 9,2) consentono codice dannoso senza autenticazione. Patch dal 21/10/2026.Che cosa fare ora →

Il sistema dei tipi di PHP

PHP è tipizzato dinamicamente, ma da PHP 7 ha un sistema dei tipi sempre più rigoroso. Qui vede i tipi, le versioni più importanti e perché i confronti stretti evitano errori di sicurezza.

Stato 6 min di letturaConoscere PHP

In breve: PHP è tipizzato dinamicamente: il tipo di un valore è definito solo in fase di esecuzione e, senza ulteriori indicazioni, PHP converte automaticamente i valori quando serve. Da PHP 7, però, parametri, valori di ritorno e proprietà possono essere dotati di tipi, e declare(strict_types=1) rende rigoroso il controllo. Chi conosce le regole e usa confronti stretti con === evita un'intera classe di errori di logica e di sicurezza.

Tipizzato dinamicamente, ma non privo di tipi

In PHP, con $preis = 19.90; non occorre indicare alcun tipo. PHP riconosce che si tratta di un numero in virgola mobile. Se il valore viene poi concatenato a una stringa, PHP lo converte. Questo comportamento si chiama type juggling, cioè conversione automatica dei tipi. Rende facile iniziare, ma può portare a risultati sorprendenti.

Per chi decide è rilevante perché molte applicazioni PHP più vecchie sono state scritte senza indicazioni di tipo. Un codice del genere è più difficile da verificare e da modernizzare. I progetti più recenti usano i tipi in modo coerente, il che rende gli errori visibili prima e permette all'analisi statica con strumenti come PHPStan o Psalm di dare davvero il meglio.

I tipi di PHP in sintesi

Il manuale PHP indica nove tipi interni che ogni espressione può avere. Di solito vengono suddivisi in tre gruppi:

Gruppo Tipi Esempio
Tipi scalari bool, int, float, string true, 42, 3.5, "Text"
Tipi composti array, object, callable [1, 2], new DateTime()
Tipi speciali null, resource null, un file aperto

Per i controlli di tipo il manuale raccomanda le funzioni is_*(), come is_int(). Per l'analisi è adatta get_debug_type(), che da PHP 8.0.0 restituisce i nomi di tipo di uso comune, mentre la più vecchia gettype() restituisce ad esempio "integer" e "double".

Accanto alla conversione automatica esiste quella esplicita: con un cast come (int) $wert o con settype() è il codice stesso a stabilire quale tipo debba avere un valore. È una pratica comune per i dati dei moduli, perché tutto ciò che arriva tramite $_GET o $_POST è inizialmente una stringa o un array. Un cast, però, non verifica se il valore avesse senso: da "abc" si ottiene in silenzio 0. Per i dati in ingresso, un vero controllo con filter_var() è quindi di solito la scelta migliore.

Anche classi e interfacce sono tipi in PHP. Una funzione può quindi richiedere che un parametro sia un oggetto di una determinata classe o che soddisfi una determinata interfaccia. Come interagiscono classi, interfacce ed enum lo spiega la pagina Programmazione a oggetti in PHP.

Dichiarazioni di tipo: da PHP 7.1 a 8.3

Le dichiarazioni di tipo stabiliscono quali valori una funzione accetta e restituisce. Il sistema dei tipi è cresciuto nel corso di molte versioni. Secondo il registro delle modifiche del manuale sono state aggiunte, tra le altre, queste possibilità:

Versione Novità
7.1.0 tipi nullable (?int), void, iterable
7.2.0 object
7.4.0 proprietà di classe tipizzate
8.0.0 tipi union (più tipi ammessi in un'unica indicazione), mixed, tipo di ritorno static
8.1.0 tipi intersection (A&B), tipo di ritorno never
8.2.0 tipi DNF, tipo letterale true, null e false come tipi autonomi
8.3.0 costanti tipizzate di classi, interfacce, trait ed enum

DNF sta per forma normale disgiuntiva e consente combinazioni come (A&B)|null. Chi pianifica le versioni di PHP vede da questa tabella anche quali strumenti del linguaggio un'applicazione presuppone.

strict_types: conversione o TypeError

Senza altre indicazioni PHP lavora in modalità con conversione. Una funzione con parametri int accetta allora anche 1.5 e ne ricava 1; da PHP 8.1 questa conversione con perdita è contrassegnata come deprecata. Con declare(strict_types=1) all'inizio del file, PHP genera invece un TypeError.

<?php
declare(strict_types=1);

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

echo summe(1, 2);      // 3
echo summe(1.5, 2.5);  // TypeError, invece di 3 in silenzio

Due sfumature sono importanti. Primo: strict_types vale per le chiamate effettuate dal file in cui compare, non per le funzioni ivi definite. Se un file senza strict_types chiama la stessa funzione, si converte. Secondo: un intero dove ci si aspetta un numero in virgola mobile è ammesso anche in modalità rigorosa.

Confronti non rigorosi e rigorosi

L'operatore == confronta dopo la conversione di tipo, === confronta valore e tipo senza conversione. Il manuale raccomanda nella maggior parte dei casi === e !==, perché le regole di conversione non sono sempre evidenti.

<?php
var_dump(0 == "a");    // PHP 7: true,  PHP 8: false
var_dump("1" == "01"); // true, entrambe sono stringhe numeriche
var_dump("1" === "01");// false, stesso tipo, ma un'altra stringa
var_dump(1 == true);   // true
var_dump(1 === true);  // false

Con PHP 8.0 i confronti tra numeri e stringhe non numeriche sono diventati più sensati. Le applicazioni più vecchie possono comportarsi in modo diverso dopo l'upgrade, ad esempio nei blocchi switch. L'espressione match, introdotta anch'essa con PHP 8.0, confronta sempre in modo rigoroso. Come i confronti non rigorosi portino a vulnerabilità, ad esempio nei controlli di token o password, lo descrive l'articolo Type juggling: i confronti non rigorosi come rischio per la sicurezza.

Tipi, upgrade e PHP2Shell

Un sistema dei tipi rigoroso rende il codice applicativo più robusto, ma non protegge dagli errori nell'interprete stesso. Le vulnerabilità PHP2Shell CVE-2026-109618 e CVE-2026-109619 si trovano nella gestione della memoria e delle richieste di PHP. Sono corrette in PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35; in seguito tutti i processi PHP devono essere riavviati.

Il sistema dei tipi gioca comunque un ruolo, e precisamente nell'upgrade. Le applicazioni ancora ferme a PHP 8.1 o precedenti non ricevono più aggiornamenti ufficiali dal progetto PHP. Un codice ben tipizzato è molto più facile da portare a una versione supportata, perché gli strumenti individuano per tempo le incompatibilità. Per i progetti più datati è utile la nostra migrazione a una versione di PHP supportata.

Consiglio

Attivi strict_types gradualmente nei file nuovi e in quelli rivisti. Così la sicurezza dei tipi cresce senza che il codice vecchio si rompa di colpo.

Come aiuta concretamente PHP SOS?

  • Verifichiamo quale versione di PHP la Sua applicazione richiede come minimo e la confrontiamo con le versioni corrette.
  • Eseguiamo l'analisi statica sul codice e segnaliamo i punti con confronti non rigorosi in controlli rilevanti per la sicurezza.
  • Pianifichiamo gli upgrade in modo che le regole di confronto modificate vengano testate prima.
  • Installiamo l'aggiornamento di PHP, riavviamo tutti i worker e documentiamo lo stato.

Domande frequenti

PHP è tipizzato in modo forte o debole?

PHP è tipizzato dinamicamente: il tipo di una variabile è definito solo in fase di esecuzione. Senza strict_types PHP converte i valori quando serve. Con le dichiarazioni di tipo e strict_types il codice può però diventare molto rigoroso.

Che cosa fa declare(strict_types=1)?

Disattiva la conversione automatica dei valori scalari per le chiamate effettuate dal file in questione. Se un valore non corrisponde al tipo dichiarato, PHP genera un TypeError. Unica eccezione è un intero dove ci si aspetta un numero in virgola mobile.

Perché 0 == "a" è falso in PHP 8 ma vero in PHP 7?

Fino a PHP 7, nel confronto con un numero una stringa non numerica veniva convertita in numero e "a" diventava 0. Da PHP 8.0 in questo caso PHP non confronta più in modo numerico, e il risultato è false.

I tipi proteggono dalle vulnerabilità in PHP stesso?

No. I tipi prevengono errori nel codice della Sua applicazione. Le vulnerabilità nell'interprete come PHP2Shell si chiudono solo con un aggiornamento di PHP. Le funzioni di tipo moderne richiedono però versioni di PHP recenti e sono quindi una buona occasione per l'upgrade.

Fonti

Contatto immediato

Ogni ora conta. Ci scriva adesso.

Descriva brevemente sistema, versione di PHP e quanto osservato. Ci faremo sentire, chiariremo la situazione e lavoreremo da remoto fino alla chiusura e alla documentazione dell'incidente.

Aiuto immediato