Effettuare upgrade a PHP 7.2

Effettuare upgrade a PHP 7.2

Quando ho scritto questo articolo, il 25 febbraio 2018, PHP 7.2 era stato rilasciato da meno di tre mesi (il 30 novembre 2017) e rappresentava per moltissime PMI italiane il primo upgrade serio dal lungo plateau di PHP 5.6, che era ancora la versione più diffusa nei server di produzione. Il salto prestazionale tra 5.6 e 7.x era documentato e visibile a occhio nudo, e nei primi mesi del 2018 la domanda concreta che ricevevo da titolari di gestionali e sviluppatori freelance era una sola: "come faccio a installarlo sul mio server Debian o Ubuntu, dato che apt-get install di default non ce l'ha?".

La risposta operativa di allora resta interessante anche oggi, ma il contesto è cambiato in modo radicale. Otto anni dopo, PHP 7.2 è in end-of-life dal 30 novembre 2020, non riceve più patch di sicurezza da oltre cinque anni, e le applicazioni che ancora ci girano sopra sono superficie d'attacco. Eppure la query "upgrade PHP 7.2 Debian" continua a essere cercata in Italia, ed è quasi sempre un sintomo: qualcuno sta toccando un sistema legacy ereditato, oppure deve adeguare uno stack non aggiornato, oppure si trova in una migrazione complessa dove 7.2 è uno step obbligato di mezzo. Questo aggiornamento dell'articolo serve esattamente quei lettori, in modo che trovino sia la procedura tecnica preservata sia il quadro 2026 sul perché restare su 7.2 oggi non è una scelta ma un debito da chiudere.

Cos'era PHP 7.2 nel 2017 e perché ha cambiato il PHP web?

PHP 7.2 era la terza release minor della grande svolta architetturale che la PHP Foundation aveva concluso con il salto da 5.6 a 7.0 nel dicembre 2015. Il refactor del Zend Engine (con la fase 3 della famosa "phpng") aveva portato un guadagno prestazionale tra il doppio e il triplo a parità di workload, e secondo il sito ufficiale del progetto ogni versione minor successiva continuava a portare incrementi del 10-12% sulla precedente. Il dato concreto di 7.2 era esattamente questo: rispetto a 7.1 si misurava in media un 11-12% in più di throughput sui benchmark sintetici computazionali, con picchi fino al 20-25% su workload tipo WordPress o frameworks con molte chiamate a function table.

Tre cose tecniche di rilievo arrivavano con 7.2 e meritano di essere ricordate. Primo, l'estensione sodium entrava nel core: prima richiedeva PECL, ora era disponibile out of the box per crittografia moderna basata su libsodium. Secondo, il supporto agli object type hints nei method signatures era stato esteso con migliore covarianza/contravarianza. Terzo, alcune funzioni considerate insicure erano state deprecate (notabilmente mcrypt, già marcata come pessima da anni e finalmente spinta verso la rimozione).

Il timing di adozione, però, era il problema reale. Le distribuzioni Linux LTS (Long Term Support) si muovono lentamente: Ubuntu 16.04 LTS era ferma su PHP 7.0, Debian 9 (Stretch) era su PHP 7.0 anche lei, e Ubuntu 17.10 (release di ottobre 2017) aveva PHP 7.1. Non esisteva ancora una distribuzione LTS che includesse PHP 7.2 nei suoi repository ufficiali. Per chi voleva 7.2 in produzione, l'unica strada praticabile era il PPA mantenuto da Ondřej Surý, Debian Developer di lunga data e packaging maintainer storico di PHP per Debian/Ubuntu. Quel PPA era la spina dorsale dell'ecosistema PHP su Linux all'epoca, e lo è tuttora nel 2026.

Perché PHP 7.2 è oggi (2026) un rischio di sicurezza?

Il dato secco: PHP 7.2 ha ricevuto la sua ultima security patch ufficiale il 30 novembre 2020. Da quel giorno, per oltre cinque anni, qualunque vulnerabilità scoperta nell'engine, nelle estensioni core, o nei moduli supportati dal team PHP non viene più corretta. La curva delle CVE di PHP non si è fermata nel 2020. È continuata, e per ogni vulnerabilità classificata come critica nelle versioni successive (7.4, 8.0, 8.1, 8.2) la domanda implicita per chi usa 7.2 è: "questo bug è presente anche nel mio engine?". Spesso la risposta è sì, e nessuno la sta correggendo per te.

Il caso più rumoroso del 2024 è stato CVE-2024-4577, una vulnerabilità di CGI argument injection su PHP eseguito in modalità CGI/CGI-FCGI che permette esecuzione di codice remoto su sistemi Windows con configurazioni specifiche. È stata patchata nelle versioni supportate al momento della scoperta (8.1.29, 8.2.20, 8.3.8) ma le versioni EOL come 7.4 e tutte le precedenti - incluso 7.2 - restano vulnerabili. CVE-2024-4577 è stata sfruttata massivamente in attacchi reali nei mesi successivi alla disclosure: gruppi APT cinesi e operazioni di ransomware automatizzate hanno usato l'exploit in fasi di initial access su web server Windows con PHP esposti.

Il calendario ufficiale di end-of-life delle versioni PHP racconta lo stato attuale del rischio in modo asciutto. Nel 2026 sono supportate solo PHP 8.2 (security-only fino al 31 dicembre 2026), 8.3 (security-only fino al 31 dicembre 2027) e 8.4 (active support, EOL fissato al 31 dicembre 2028). Tutto il resto, da PHP 5.6 a PHP 8.1, è in EOL con grado di esposizione crescente in funzione di quanto è vecchio.

Per una PMI italiana che ha ancora applicazioni in produzione su PHP 7.2 nel 2026, il calcolo del rischio non è più "vale la pena migrare?" ma "quanto costerebbe un incidente di sicurezza riconducibile a un engine non patchato da cinque anni?". È una domanda diversa, e la risposta in termini contrattuali (specie sotto NIS2 per i settori essenziali e GDPR per il trattamento dati) è che la responsabilità del titolare aumenta in modo non lineare quando il difetto è imputabile a software notoriamente fuori supporto.

Come si installa PHP 7.2 oggi via ondrej/sury (procedura aggiornata)?

Per chi ha effettivo bisogno di PHP 7.2 oggi (sistemi legacy, container di test, riproduzione di bug storici, percorso di migrazione step-by-step), la procedura tramite il PPA di Ondřej Surý è ancora funzionante nel 2026, anche se con qualche caveat di compatibilità con le distribuzioni più recenti. Il PPA continua a essere mantenuto attivamente: a dicembre 2025 il repository GitHub oerdnj/deb.sury.org è stato archiviato in modalità read-only per consolidamento del progetto, ma il PPA principale resta operativo per Ubuntu LTS 20.04 (Focal), 22.04 (Jammy) e 24.04 (Noble), oltre alle versioni Debian oldstable e stable.

Su Ubuntu LTS la procedura è asciutta. Aggiungere il PPA, aggiornare gli indici, e installare i pacchetti php7.2-* desiderati:

sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install -y libapache2-mod-php7.2 \
    php7.2 php7.2-cli php7.2-fpm php7.2-common \
    php7.2-mysql php7.2-curl php7.2-gd \
    php7.2-mbstring php7.2-xml php7.2-zip \
    php7.2-intl php7.2-bcmath php7.2-soap

Su Debian la procedura richiede l'aggiunta manuale del repository con la chiave GPG firmata da Surý:

sudo apt-get install -y apt-transport-https lsb-release ca-certificates curl
sudo curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg
sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
sudo apt-get update
sudo apt-get install -y php7.2 php7.2-cli php7.2-fpm php7.2-common \
    php7.2-mysql php7.2-curl php7.2-gd \
    php7.2-mbstring php7.2-xml php7.2-zip \
    php7.2-intl php7.2-bcmath

Note operative aggiornate al 2026 che non c'erano nell'articolo originale del 2018.

La prima è che il PPA permette PHP co-installabili, cioè 7.2, 7.4, 8.1, 8.2, 8.3 e 8.4 possono convivere sullo stesso server. Lo strumento update-alternatives gestisce quale versione viene chiamata da php di default, ma php7.2, php8.4, eccetera sono sempre disponibili nominativi. Per workflow di migrazione questo è oro: si può eseguire l'applicazione legacy su 7.2 mentre i nuovi servizi girano su 8.4 nello stesso server.

La seconda è che le distribuzioni non-LTS di Ubuntu (es. 25.04, 25.10) non sono ufficialmente supportate dal PPA. Il maintainer ha esplicitamente ridotto il supporto alle sole LTS biennalmente per questioni di sostenibilità. Per chi è su distribuzioni interim, l'unica strada legittima oggi è passare a una LTS o usare container con un'immagine LTS dedicata.

La terza è che alcuni sotto-PPA storici sono diventati irraggiungibili nel 2025 (notabilmente ppa:ondrej/pkg-gearman). Se la tua applicazione legacy dipende da estensioni esotiche, verifica caso per caso prima di pianificare l'upgrade.

Come si pianifica la migrazione da PHP 7.2 a PHP 8.x?

La migrazione da PHP 7.2 a una versione supportata nel 2026 (idealmente PHP 8.3 o 8.4) non è un singolo apt-get. È un percorso che, nelle codebase legacy che ho visto in audit, richiede tipicamente da quattro a dodici settimane di lavoro a seconda della dimensione del codice e della copertura di test esistente. La struttura che applico, e che documento in dettaglio nella mia guida alla migrazione da PHP 5.6 a PHP 8 per applicazioni legacy in produzione, prevede sei fasi.

Prima fase: inventario delle dipendenze. PHP 7.2 → 8.0 introduce break radicali. La libreria mcrypt (rimossa in 7.2 stessa) è solo l'inizio: ext/recode, ext/wddx, ext/xmlrpc spariscono in 8.0. Le funzioni each(), create_function(), assert() con argomento stringa, e tutto il blocco delle vecchie API mysql_* sono rimosse o trasformate. L'inventario completo delle estensioni e funzioni usate dalla codebase è il primo deliverable, e si fa con tooling automatico (PHPStan a livello 0 con php-version 8.x, Rector con set di regole PHP74_PHP80, Psalm con stub di compatibilità).

Seconda fase: aggiornamento di tutte le dipendenze Composer alle versioni che supportano PHP 8. Molte librerie storiche italiane (gestionali con Symfony 2.x, applicazioni con Zend Framework 1, vecchi pacchetti di e-commerce custom) richiedono un percorso intermedio: prima salire alla versione più recente che supporta sia 7.2 sia 8.0, poi salire alla versione che richiede 8.0+. Saltare un ponte significa quasi sempre rompere qualcosa.

Terza fase: salita iterativa per minor version. PHP 7.2 → 7.4 → 8.0 → 8.1 → 8.3. Ogni step richiede un round di test funzionali. La regola che ho consolidato nei progetti è: mai due minor saltate insieme. Il debugging diventa esponenzialmente più costoso.

Quarta fase: refactoring del codice incompatibile. Qui il valore degli strumenti automatici esplode: Rector applica trasformazioni AST che convertono pattern legacy in equivalenti moderni in modo deterministico. Nelle migrazioni recenti che ho condotto, Rector con i set PHP74_PHP80, PHP80_PHP81, PHP81_PHP83 riduce il lavoro manuale di una percentuale che oscilla tra il 60% e l'80% sulla mia statistica personale.

Quinta fase: validazione di sicurezza. Una volta che la codebase compila e i test passano, vanno verificate le configurazioni php.ini: opcache, memory_limit, max_execution_time, session security headers, disable_functions per mitigare classi di attacco. Su 8.x le configurazioni di default sono migliori, ma alcune impostazioni storiche di 7.2 vanno riviste manualmente.

Sesta fase: deployment graduale. Il pattern che applico è blue-green con un canary: si fa girare la nuova versione sul 5% del traffico per 48 ore, si misurano error rate e latenza P95, si scala progressivamente. Per workflow LLM-assisted moderni che integro nei progetti più recenti, ho strutturato il processo come pipeline con Claude Code, dove ogni step di refactor passa attraverso review automatizzato e validazione semantica prima di entrare in produzione.

Tre punti dolenti specifici di chi viene da PHP 7.2 nel 2026 meritano un'attenzione separata, perché sono esattamente i pattern dove ho visto migrazioni andare in difficoltà. Il primo riguarda le sessioni: PHP 8.0 ha cambiato il comportamento di session_start() in presenza di output già inviato, ed è diventato più stretto sui parametri di configurazione session.cookie_samesite e session.use_strict_mode. Codebase 7.2 che assumevano sessioni implicite e gestione cookie permissiva richiedono spesso ritocchi puntuali, soprattutto se interagiscono con front-end SPA che fanno chiamate cross-origin. Il secondo riguarda la gestione dei tipi: PHP 8.0 ha introdotto strict union types e ha eliminato il fallback silenzioso da string a int per certe operazioni numeriche. Confronti del tipo 0 == "stringa" non sono più magicamente true, e in codice legacy questo cambio rompe condizioni che apparivano corrette per anni. Il terzo riguarda PCRE: la migrazione a PCRE2 in PHP 7.3 (e mantenuta in 8.x) ha cambiato sottilmente la sintassi accettata dalle regex. Pattern con \K e lookbehind variabile possono comportarsi diversamente, ed è una classe di bug particolarmente subdola perché si manifesta solo su input specifici.

Se hai un'applicazione su PHP 7.2 in produzione e stai valutando come muoverti, il mio profilo professionale raccoglie i dettagli del lavoro che faccio su modernizzazione PHP per PMI italiane, dal triage iniziale fino al deployment in produzione. Il punto chiave è che ogni mese passato su 7.2 è un mese di rischio composto: la finestra di esposizione cresce, la complessità del salto cresce con essa (ogni nuova feature scritta sul vecchio engine è codice da rivedere durante la migrazione), e il costo finale della migrazione cresce di conseguenza. Un audit di una settimana spesso fa risparmiare mesi di lavoro su un percorso lungo, perché identifica l'ordine corretto degli interventi.

Le risorse esterne autorevoli che continuo a usare come riferimento sono il calendario ufficiale di end-of-life di PHP su endoflife.date, il PPA di Ondřej Surý su Launchpad per pacchetti, e la pagina ufficiale delle versioni supportate sul sito php.net per il calendario delle release. La pagina Surý su deb.sury.org contiene istruzioni sempre aggiornate per l'aggiunta del repository su Debian.

Se la tua infrastruttura include applicazioni legacy PHP che meritano un percorso di modernizzazione strutturato, e vuoi capire da dove cominciare partendo da una mappa del rischio reale invece che da una lista di buone intenzioni, contattami direttamente e organizziamo un audit di triage. Spesso è la differenza tra spendere bene e spendere due volte: chi prova a fare la migrazione da PHP 7.2 a 8.x senza una strategia ordinata di solito completa il primo step, scopre che gli ultimi due step erano dipendenti da scelte fatte all'inizio, e deve tornare indietro pagando il refactoring due volte. Vale la pena partire con la mappa giusta, anche solo per evitare quella seconda volta.

Ultima modifica: