PHP alimenta circa il 74% dei siti web di cui è noto il linguaggio lato server, secondo le rilevazioni di W3Techs. WordPress da solo copre oltre il 43% di tutto il web. Numeri che raccontano una verità scomoda per chi continua a dichiarare morto questo linguaggio: PHP non è morto, ha solo smesso di fare rumore.
E mentre faceva silenzio, è arrivato PHP 8.5, rilasciato il 20 novembre 2025. Porta cose che molti sviluppatori aspettavano da anni: il pipe operator, il clone con modifica delle proprietà, un’estensione URI nativa e un paio di funzioni array che colmano una lacuna vecchia di una decade.
In questo articolo vediamo le novità più rilevanti, con esempi di codice verificati sulla release finale. Quando una sintassi è soggetta a precisazioni la segnalo, perché tra una RFC in voto e il codice che gira in produzione la distanza a volte è notevole.
Dove eravamo rimasti: da 8.0 a 8.4
Per capire il valore di 8.5 conviene ricordare la traiettoria recente del linguaggio. PHP 8.0 ha introdotto il JIT, i named arguments, i constructor property promotion, il match. Le versioni successive hanno aggiunto enum, readonly properties, fibers. PHP 8.4, in particolare, ha portato due funzionalità che pesano molto in ottica codice moderno: le Property Hooks e l’Asymmetric Visibility.
Le Property Hooks permettono di definire logica di lettura e scrittura su una proprietà senza scrivere getter e setter espliciti. L’Asymmetric Visibility consente di avere una proprietà pubblica in lettura ma privata o protetta in scrittura, riducendo il boilerplate dei value object. PHP 8.5 estende l’asymmetric visibility anche alle proprietà statiche.
Tengo a precisare l’attribuzione perché conta: Property Hooks e Asymmetric Visibility sono di PHP 8.4, non di 8.5. Le novità proprie di 8.5 sono quelle che seguono.
Pipe operator: il codice si legge come si pensa
Questa è probabilmente la novità più attesa. Il pipe operator (|>) prende il valore alla sua sinistra e lo passa come unico argomento alla callable alla sua destra, restituendo il risultato. La forza sta nel concatenamento: si legge da sinistra a destra, seguendo il flusso reale dei dati.
Prima, una serie di trasformazioni si scriveva con funzioni annidate, da leggere dall’interno verso l’esterno:
$result = strtoupper(
str_shuffle(
trim($input)
)
);
Con il pipe operator diventa:
$result = $input
|> trim(...)
|> str_shuffle(...)
|> strtoupper(...);
Qui c’è un dettaglio tecnico che fa la differenza tra un esempio che funziona e uno che dà errore. La callable a destra deve accettare il valore come unico argomento. Per le funzioni standard si usa la sintassi first-class callable introdotta in PHP 8.1, cioè trim(...), dove i tre punti dicono al motore di trattare la funzione come callable.
Quando servono argomenti aggiuntivi, come nel caso di array_filter e array_map che vogliono l’array come secondo argomento, si usa una arrow function:
$result = $numbers
|> (fn($arr) => array_filter($arr, fn($x) => $x > 0))
|> (fn($arr) => array_map(fn($x) => $x * 2, $arr))
|> array_sum(...);
Due avvertenze pratiche. La prima: le funzioni con primo parametro passato per riferimento, come sort, array_pop, array_shift, non possono essere usate come first-class callable in un pipe; in genere conviene chiamarle fuori dalla catena e passare il risultato. La seconda: il placeholder, quel ? o $$ che alcuni esempi in giro mostrano, appartiene alla partial function application, una proposta separata rinviata a PHP 8.6 e non entrata in 8.5. Se trovate codice 8.5 con $$ nel pipe, è errato.
Il pipe rende davvero con tre o più trasformazioni in sequenza. Per una o due operazioni il codice tradizionale spesso resta più leggibile.
clone with: immutabilità senza il boilerplate
Lavorare con value object immutabili in PHP ha sempre richiesto pattern verbosi. Per creare una copia con un campo diverso, si clonava l’oggetto e poi si modificava la copia, perdendo di fatto l’immutabilità durante il processo:
$new = clone $user;
$new->name = 'Mario';
$new->email = '[email protected]';
PHP 8.5 introduce la possibilità di modificare le proprietà durante la clonazione. La sintassi finale è funzionale:
$new = clone($user, [
'name' => 'Mario',
'email' => '[email protected]',
]);
L’oggetto originale resta intatto e la copia nasce già nello stato desiderato. Questo semplifica molto il lavoro con i value object immutabili e con il pattern “with-er” sulle classi readonly, dove prima servivano metodi withX() scritti a mano per ogni proprietà.
Una precisazione tecnica importante: clone with non esegue una clonazione profonda. Gli oggetti annidati restano riferimenti condivisi. Se serve una copia profonda, va implementato __clone().
Estensione URI nativa: basta parse_url()
PHP nasce per il web, e il web si regge su URI e URL. Eppure lo strumento storico per lavorarci, `parse_url()`, è datato e non segue gli standard internazionali pubblicati. PHP 8.5 aggiunge un’estensione URI nativa per analizzare, normalizzare e gestire URL secondo gli standard RFC 3986 e WHATWG URL.
L’idea è gestire gli URL come oggetti: immutabili, concatenabili, con validazione. Un esempio del tipo di operazione che l’estensione abilita:
$uri = Uri\Rfc3986\Uri::parse('https://miosito.it/api/utenti?pagina=2');
$uri->getHost(); // "miosito.it"
$uri->getPath(); // "/api/utenti"
$uri->getQuery(); // "pagina=2"
L’estensione espone più classi, tra cui implementazioni conformi a RFC 3986 e alla specifica WHATWG. Per i nomi esatti delle classi e dei metodi conviene fare riferimento alla documentazione ufficiale dell’estensione, perché la superficie dell’API è ampia e i dettagli sono quelli che cambiano più spesso tra le note di rilascio. Il concetto resta solido: finalmente un oggetto URI nativo, immutabile e standard-compliant, senza dipendere da librerie esterne.
array_first() e array_last(): piccole funzioni, grande comodità
Una lacuna vecchia di anni si chiude. PHP 7.3 aveva introdotto `array_key_first()` e `array_key_last()`, che restituiscono le chiavi. Per ottenere i valori bisognava ricorrere a `reset()` ed `end()`, che però spostano il puntatore interno dell’array, oppure a costrutti come `$array[array_key_first($array)]`, poco leggibili.
PHP 8.5 aggiunge `array_first()` e `array_last()`, che restituiscono direttamente il primo e l’ultimo valore senza toccare il puntatore interno e senza essere distruttive:
$data = [10, 20, 30, 40, 50];
$first = array_first($data); // 10
$last = array_last($data); // 50
array_first([]); // null
array_last([]); // null
Funzionano anche con chiavi non sequenziali, restituendo il valore nel primo o ultimo ordine interno. Una nota di compatibilità: se nel vostro codice avete già definito funzioni globali con questi nomi, ci sarà un conflitto di ridichiarazione da gestire con `function_exists` o un namespace.
Altre novità e deprecazioni
Tra le altre novità di 8.5 segnalo i backtrace per gli errori fatali, che rendono il debugging molto più rapido, e l’attributo `#[\NoDiscard]`, che avvisa quando il valore di ritorno di una funzione non viene usato. OPcache, inoltre, è ora sempre compilato a partire da 8.5.
Sul fronte deprecazioni, ogni release ne introduce di nuove come preavviso dei cambiamenti della major successiva. Tra le deprecazioni previste in 8.5 figura la rimozione di tutte le costanti `MHASH_*`, che spinge verso alternative più sicure. Per l’elenco completo e aggiornato conviene consultare la pagina ufficiale delle modifiche retrocompatibili, perché i dettagli delle deprecazioni sono il punto in cui le note preliminari divergono più spesso dalla release finale.
Compatibilità con i framework
Una raccomandazione metodologica più che una notizia: prima di aggiornare in produzione, verificate sempre la matrice di compatibilità ufficiale del vostro framework. Laravel, Symfony, CodeIgniter 4 e WordPress aggiornano il supporto alle nuove versioni di PHP con tempistiche proprie, e dichiarare a priori “supportato da X” rischia di invecchiare male nel giro di poche settimane. La fonte affidabile è sempre la documentazione del singolo progetto.
Vale anche la regola di buon senso di chi gestisce ambienti reali: non installare una nuova minor in produzione il giorno del rilascio. Conviene attendere almeno la prima patch (in questo caso 8.5.1) e far girare prima la suite di test.
In sintesi
Per chi dice che php è morto questa è la dimostrazione invece che PHP non è morto, sta solo smettendo di fare rumore. PHP 8.5, novembre 2025, porta il pipe operator, il clone con modifica delle proprietà, l’estensione URI nativa e le funzioni `array_first()` / `array_last()`. Sono aggiunte che migliorano la leggibilità del codice e la qualità della vita di chi scrive PHP ogni giorno, costruite sopra le fondamenta poste da 8.4 con Property Hooks e Asymmetric Visibility.
Se lavorate con PHP, vale la pena pianificare l’aggiornamento. Verificate la compatibilità, testate, e godetevi una sintassi che, in più punti, finalmente si legge come si pensa.
Fonti
- PHP.net, “PHP 8.5 Release Announcement“, pagina ufficiale di rilascio: https://www.php.net/releases/8.5/en.php
- PHP.net, “Functional (pipe operator) — Manual“, riferimento ufficiale alla sintassi del pipe operator: https://www.php.net/manual/en/language.operators.functional.php
- Zend, “PHP 8.5: New Features and Deprecations“, di Matthew Weier O’Phinney: https://www.zend.com/blog/php-8-5-features
- Zend, “Using the PHP Pipe Operator“, chiarisce la sintassi first-class callable e la posizione della partial function application: https://www.zend.com/blog/php-pipe-operator
- stitcher.io (Brent Roose), *What’s new in PHP 8.5*: https://stitcher.io/blog/new-in-php-85
- PHP.Watch, “Pipe operator (`|>`)“, dettagli sui vincoli dei parametri by-reference: https://php.watch/versions/8.5/pipe-operator
- PHP.Watch, “New `array_first` and `array_last` functions“, firme e comportamento sui casi limite: https://php.watch/versions/8.5/array_first-array_last
- The PHP Foundation, “PHP 8.5 Adds Pipe Operator“, di Larry Garfield (autore della RFC): https://thephp.foundation/blog/2025/07/11/php-85-adds-pipe-operator/
- Benjamin Crozat, “PHP 8.5: 15 new features and changes“, calendario di rilascio e ciclo di supporto: https://benjamincrozat.com/php-85
- W3Techs, “Usage statistics of PHP for websites“, fonte del dato sulla diffusione di PHP: https://w3techs.com/technologies/details/pl-php