Cosa arriva in PHP 8.6 e se conviene aggiornare subito
Il 19 novembre 2026 esce PHP 8.6, puntuale come ogni novembre da quando il progetto ha adottato la cadenza annuale: la feature freeze è scattata il 22 settembre, le release candidate girano da fine settembre, e a una settimana dalla GA il contenuto è congelato e si può raccontare senza condizionali. Scrivo PHP dal 2003, ho attraversato tutte le transizioni da PHP 4 in avanti, e ho sviluppato un metro semplice per pesare le release annuali: quante feature cambiano il modo in cui scriverò codice l'anno prossimo, e quante sono rifiniture che il codice le attraversa senza accorgersene. Con questo metro, la 8.6 è una release più interessante della media: la partial function application è una feature della prima categoria, di quelle che entrano nello stile di scrittura e non ne escono più, e chiude un discorso rimasto aperto per cinque anni nella comunità; attorno le fanno compagnia ottimizzazioni delle closure che regalano prestazioni senza chiedere niente, un sistema di errori strutturati per gli stream che chi fa I/O difensivo aspettava da un decennio, e la consueta dote di deprecazioni da passare al setaccio. In questo articolo scendo nel dettaglio di cosa arriva, con il codice, e chiudo con la domanda pratica del titolo: cosa fare adesso, questa settimana, a seconda di dove sei nel ciclo delle versioni.
Qual è la novità che cambia il modo di scrivere PHP?
La risposta secca: la partial function application, la capacità di chiamare una funzione fornendo solo una parte degli argomenti e ottenere in cambio una closure che aspetta i rimanenti. La sintassi usa due segnaposto: ? per un singolo argomento da fornire dopo, ... per tutti i rimanenti, e la seconda forma generalizza la sintassi dei first-class callable che conosci dalla 8.1: applicaIva(?, ...) fissa niente e chiede tutto, applicaIva(?, 22.0) fissa l'aliquota e chiede l'importo. Il valore si vede subito nel codice di tutti i giorni, dove oggi il rumore delle arrow function avvolge chiamate che di logica propria non ne hanno:
// Oggi: la closure esiste solo per fissare il secondo argomento
$importiConIva = array_map(
fn (float $importo): float => applicaIva($importo, 22.0),
$importiNetti
);
// Con PHP 8.6: il segnaposto dichiara l'argomento mancante
$importiConIva = array_map(applicaIva(?, 22.0), $importiNetti);La closure prodotta non è un involucro anonimo qualunque: conserva nomi, tipi e default dei parametri della funzione originale, quindi la riflessione, l'analisi statica e gli IDE continuano a vedere la firma vera. E c'è una semantica precisa che va capita subito perché è una scelta di design, non un dettaglio: gli argomenti forniti vengono valutati alla creazione della partial, non alla chiamata. Se scrivi applicaIva(?, $aliquota()), la funzione $aliquota() viene eseguita una volta, nel momento in cui costruisci la partial, e il valore resta congelato dentro la closure. È il comportamento giusto per la prevedibilità, ed è anche una piccola trappola per chi si aspettava una valutazione pigra: meglio saperlo dal primo giorno.
La storia dietro la feature merita due righe perché racconta come matura il linguaggio: una prima versione della proposta fu bocciata nel 2021, giudicata troppo complessa nel rapporto fra costi di implementazione e benefici; la versione ripresentata per la 8.6 è passata 33 voti a 0, un'unanimità rara, perché nel frattempo era cambiato il contesto. Il contesto ha un nome preciso: il pipe operator arrivato con PHP 8.5, di cui ho scritto chiedendomi se fosse leggibilità reale o zucchero sintattico. Il pipe della 8.5 funzionava bene con le funzioni a un argomento e diventava goffo appena serviva fissarne altri; la PFA è esattamente il pezzo che mancava, e la coppia completa si legge così:
// Pipeline di normalizzazione di uno slug, 8.5 + 8.6 insieme
$slug = $titolo
|> trim(?)
|> mb_strtolower(?)
|> str_replace(' ', '-', ?);Ogni passaggio dichiara dove entra il valore che scorre nella pipeline, anche quando non è il primo argomento, che con str_replace è il caso reale. Preso da solo, il pipe era una scommessa sulla direzione del linguaggio; con la PFA la scommessa è pagata, e la scrittura per pipeline in PHP smette di essere un esercizio di stile per diventare un'opzione matura. Il mio giudizio onesto, da usare fra un anno per verificare: la PFA verrà adottata in fretta nel codice funzionale-leggero, array_map, array_filter, pipeline di trasformazione, e lì ridurrà rumore vero; il rischio, come per ogni sintassi espressiva, è l'abuso nelle codebase dove una closure esplicita con un nome avrebbe raccontato meglio l'intenzione. La sintassi nuova non cambia la regola vecchia: si scrive per chi legge.
Il resto che conta per la produzione
Della lista completa, che trovi con lo stato di ogni RFC su PHP.Watch nella pagina dedicata alla 8.6, seleziono ciò che tocca davvero il codice di produzione, nell'ordine in cui credo lo incontrerai.
Le ottimizzazioni delle closure sono il regalo silenzioso della release: il motore ora inferisce da solo il modificatore static per le closure che non usano $this e mette in cache le closure completamente stateless invece di ricrearle a ogni passaggio. Tradotto: il codice pieno di callback, che nel PHP moderno è la norma, alloca meno oggetti e lavora meno, senza che tu cambi una riga. È la categoria di miglioramento che preferisco, quella che si incassa con il solo upgrade, ed è anche un segnale di dove guarda il core team: se le closure diventano più economiche proprio mentre PFA le moltiplica, il disegno è coerente.
Gli errori strutturati sugli stream sono la novità che chi scrive codice difensivo apprezzerà più di tutte. Oggi un fallimento su un'operazione di stream produce un warning testuale da intercettare con acrobazie; la 8.6 introduce un'opzione di contesto error_mode per scegliere fra warning, eccezioni o silenzio, e la funzione stream_last_errors() che restituisce oggetti errore strutturati, con oltre cinquanta codici semantici a catalogo. Per chi maneggia file, socket e API remote con la disciplina che il codice di produzione richiede, è la differenza fra fare parsing di stringhe di errore e ragionare su casi tipizzati: una di quelle rifiniture infrastrutturali che non fanno titolo e migliorano la robustezza di tutto ciò che ci passa sopra.
Il capitolo utilità completa il quadro: l'estensione URI arrivata con la 8.5 guadagna le classi builder per assemblare URI senza oggetti intermedi; gli enum possono finalmente definire __debugInfo(), quindi il var_dump() di un enum smette di essere un geroglifico; la diagnostica JSON migliora la localizzazione degli errori di json_decode(); e pack()/unpack() estendono i modificatori di endianness ai formati in virgola mobile, dettaglio di nicchia finché non lavori con protocolli binari, dove diventa il dettaglio. Sul fronte opposto, le deprecazioni: la RFC ombrello della 8.6 ne raccoglie diverse, votate una per una, fra cui strcoll(), la costante SORT_LOCALE_STRING e il passaggio di oggetti ad alcune funzioni di array e zlib. Nessuna è drammatica, ma la disciplina è sempre la stessa: si cerca nel codice adesso, non quando i log di produzione si riempiono di deprecation notice. Il giro di controllo costa cinque minuti:
grep -rn --include="*.php" -E "strcoll\(|SORT_LOCALE_STRING" src/ app/
# checking usages flagged by the umbrella deprecation RFCUn risultato vuoto è un pensiero in meno; ogni riga trovata è un piccolo lavoro da fare in un martedì tranquillo invece che a metà di un upgrade. E una nota su cosa NON c'è, perché l'attesa era palpabile: il pattern matching resta materia di discussione per le versioni future, e ogni pianificazione seria deve assumere che non esista finché una RFC non passa.
La qualità di una release annuale non si misura dal numero di feature ma dalla coerenza della direzione. La 8.6 è coerente: PFA completa il pipe, le closure ottimizzate sostengono entrambi, gli errori strutturati continuano la lenta bonifica del PHP antico. Chi ha seguito le ultime tre release riconosce il disegno: il linguaggio sta diventando più espressivo e più prevedibile insieme, che è la combinazione difficile.
C'è infine il piano infrastrutturale, che per chi legge questo blog dai VPS è la domanda gemella: dove la troverò, la 8.6? Non nei repository della tua distribuzione: Debian 13 trixie resta su PHP 8.4 per il suo intero ciclo, com'è giusto che una stable faccia. Le strade sono le due di sempre, i repository di terze parti storicamente affidabili dell'ecosistema Debian oppure i container, e la seconda è quella che raccomando sempre più spesso, perché disaccoppiare la versione di PHP dal ciclo di vita del sistema operativo è la scelta che rende ogni upgrade futuro, di PHP o di sistema, un evento indipendente e piccolo invece che un intreccio. Chi ha vissuto un major upgrade di sistema con il PHP di sistema in produzione sa esattamente di cosa parlo.
E quindi: aggiornare subito?
Domanda giusta, momento sbagliato per una risposta unica: dipende da dove sei, e la settimana prima della GA è il momento di prepararsi, non di decidere alla cieca. Tre situazioni coprono la quasi totalità dei casi reali che incontro.
Se sei ancora su PHP 8.2, la 8.6 non è il tuo argomento: il tuo argomento è il calendario, perché il supporto di sicurezza della 8.2 finisce il 31 dicembre 2026, fra sette settimane, come certifica la pagina ufficiale delle versioni supportate. La rotta giusta non è il salto acrobatico all'ultima versione appena nata, è la migrazione ordinata verso la 8.4, che resta pienamente supportata a lungo e ha un ecosistema completamente assestato; l'ho argomentata nel dettaglio nel piano di migrazione per le scadenze EOL del 2026, e se non è ancora partita, questa settimana vale più per quel piano che per qualunque feature nuova. Un punto di partenza rapido per capire dove sei: il mio strumento di audit del composer.json legge il tuo progetto e segnala versioni dichiarate, vincoli e componenti a fine vita in un minuto.
Se sei su 8.4 o 8.5 in produzione, la regola che applico da vent'anni sulle release di novembre è di una noia esemplare: la .0 non tocca la produzione. Non per sfiducia nel core team, ma per l'ecosistema: estensioni PECL, tooling, librerie con dichiarazioni di compatibilità da aggiornare, e quella coda di casi limite che emerge solo quando milioni di macchine eseguono il codice vero. Le release 8.6.1 e 8.6.2 arrivano con cadenza mensile e assorbono l'assestamento; la produzione conservativa sale bene in primavera, con l'ecosistema allineato e i vantaggi intatti. Aggiornare presto e aggiornare subito non sono la stessa cosa: il primo è un obiettivo sano, il secondo è un rischio senza premio.
Se mantieni librerie o hai una CI seria, il discorso si ribalta: il tuo momento è adesso, ed è già in ritardo di un mese. Aggiungere la 8.6 in RC alla matrice di test costa una riga di configurazione e ti dice oggi, mentre i problemi sono gratis, se qualcosa si rompe: le deprecazioni che toccano il tuo codice, i test che assumono comportamenti cambiati, le dipendenze che dichiarano vincoli troppo stretti. È il lavoro che separa chi il 19 novembre pubblica il supporto alla 8.6 da chi, a dicembre, apre le issue degli altri chiedendo quando arriva; e per una libreria pubblica la tempestività del supporto è reputazione misurabile, la vetrina più economica che esista. Nel mio lavoro sulle codebase dei clienti questa preparazione d'anticipo è la norma, non l'eccezione: nel mio profilo professionale trovi come imposto migrazioni e cicli di aggiornamento PHP che arrivano alle scadenze con mesi di margine invece che con settimane di ritardo.
Il quadro d'insieme, per chiudere: la 8.6 è una buona release che arriva in un momento di calendario affollato, con la 8.2 che muore a fine anno e mezza Italia PHP ancora sopra. La priorità operativa la detta l'EOL, non la novità; ma la novità merita attenzione vera, perché la coppia pipe più PFA è il cambiamento di scrittura più significativo degli ultimi anni di PHP, e chi lo assimila presto scriverà codice più pulito per il resto del decennio. La settimana giusta per giocarci è questa, in un container con la RC, sui propri casi reali. E se la tua situazione è la prima delle tre, la 8.2 in produzione con il conto alla rovescia che corre, contattami per una consulenza: una migrazione pianificata a novembre è routine, la stessa migrazione improvvisata a gennaio, con il supporto già finito, è un'altra storia, e la differenza di costo fra le due la conosco per averle viste entrambe molte volte.
