Modernizzare un'applicazione PHP legacy senza riscrivere tutto
Strategie concrete per migliorare un progetto PHP datato: refactoring incrementale, test e aggiornamento graduale.
5 min di letturaPHP
Luigi Iadicola, Programmatore - Napoli
In questo articolo
Riscrivere da zero è quasi sempre la scelta sbagliata
La tentazione di buttare via tutto e ripartire da zero è forte quando ci si trova davanti a un'applicazione PHP legacy vecchia di anni, con codice misto, nessun test e una struttura che nessuno ricorda perché è fatta così. Ma la riscrittura completa è rischiosa: si perde la conoscenza di business accumulata nel codice, si sottostimano i tempi e si resta senza prodotto funzionante per mesi — a volte anni.
Joel Spolsky lo scrisse nel 2000 e vale ancora oggi: la riscrittura da zero è il peggior errore strategico che un team di sviluppo possa fare. Il vecchio codice, per quanto brutto, funziona. Contiene anni di bug fix, edge case gestiti e regole di business che nessun documento ha mai catturato. Buttarlo via significa perdere tutto questo e sperare di riscriverlo correttamente al primo tentativo — cosa che non succede mai.
L'alternativa è il refactoring incrementale: migliorare il sistema un pezzo alla volta, senza mai interrompere il funzionamento. È meno spettacolare, ma funziona. E soprattutto, produce valore dal giorno uno — non dopo sei mesi di riscrittura senza niente da mostrare.
Strategia pratica di modernizzazione
Il primo passo non è toccare il codice: è capire cosa fa. Mappare i flussi critici, identificare le parti più fragili, aggiungere test sulle funzioni che non possono rompersi. Solo dopo si inizia a isolare, semplificare e aggiornare. Questo approccio richiede disciplina, ma è l'unico che funziona in modo affidabile su sistemi in produzione.
Fase 1: Stabilizzare e proteggere
Prima di qualsiasi modifica, serve una rete di sicurezza. Questo significa aggiungere test automatici sui percorsi critici dell'applicazione. Non serve una copertura del 100% — serve testare le funzioni che, se si rompono, fermano il business. Autenticazione, flussi di pagamento, generazione documenti, importazione dati: parti da lì.
In parallelo, configura un sistema di version control se non c'è già (incredibilmente, molte applicazioni legacy non usano git), e un ambiente di staging che replica la produzione. Ogni modifica deve essere testabile in un ambiente sicuro prima di andare live.
Fase 2: Isolare e separare
Il problema più comune del codice legacy è l'accoppiamento: la logica di business è mischiata con la presentazione, le query SQL sono sparse ovunque, la configurazione è codificata in costanti globali. Il lavoro di questa fase è separare le responsabilità senza cambiare il comportamento.
Tecniche concrete che funzionano:
- Introdurre autoloading e namespacing dove manca — eliminare i require manuali è il primo passo verso una struttura moderna
- Estrarre la logica di business in classi dedicate — separare il "cosa fa" dal "come lo mostra"
- Sostituire query inline con un layer di accesso dati strutturato — centralizzare le query rende il codice più sicuro e testabile
- Migrare la configurazione da costanti sparse a un sistema centralizzato — un unico punto dove cambiare ambiente
- Isolare le dipendenze esterne dietro interfacce — se domani cambi il gateway di pagamento, cambi una classe, non cento file
Fase 3: Aggiornare e modernizzare
Con i test in posizione e il codice separato in moduli, si può iniziare ad aggiornare. Aggiornare la versione di PHP è spesso il primo passo più impattante: ogni versione maggiore porta miglioramenti di performance significativi (PHP 8.x è mediamente 2-3 volte più veloce di PHP 5.6), oltre a funzionalità del linguaggio che rendono il codice più leggibile e sicuro.
L'aggiornamento di PHP va fatto gradualmente: prima risolvere tutti i deprecation warning della versione attuale, poi salire di una versione alla volta. Ogni step viene testato e validato prima di procedere al successivo. Saltare versioni è possibile ma rischioso — meglio un percorso più lungo ma controllato.
Errori comuni da evitare
In anni di lavoro su codice legacy, ho visto gli stessi errori ripetersi:
- Riscrivere tutto insieme: il refactoring incrementale funziona perché ogni passo è piccolo e reversibile. Cambiare tutto in un colpo è una riscrittura mascherata
- Non aggiungere test prima di modificare: senza test stai giocando alla roulette russa con il codice in produzione
- Inseguire la perfezione: l'obiettivo non è il codice perfetto, è il codice migliore di prima. Il meglio è nemico del bene
- Sottovalutare la documentazione: ogni scoperta sul comportamento del sistema legacy va documentata. Tra sei mesi non ricorderai perché quella funzione ha quel workaround
- Non coinvolgere chi usa il sistema: gli utenti conoscono edge case che non sono documentati da nessuna parte
Risultati concreti
Ogni intervento migliora la situazione senza fermare il business. Dopo qualche mese di lavoro costante, l'applicazione è irriconoscibile — e non ha mai smesso di funzionare. Ho visto applicazioni PHP legacy passare da incubi di manutenzione a sistemi moderni, testati e piacevoli da sviluppare, in 6-12 mesi di lavoro incrementale.
I benefici si vedono da subito: meno bug in produzione, deploy più frequenti e sicuri, sviluppo di nuove feature più veloce, onboarding di nuovi sviluppatori più semplice. E il ROI del refactoring incrementale è misurabile: meno ore spese a correggere bug, meno downtime, più capacità di evolvere il prodotto.
Il refactoring di codice legacy non è il lavoro più glamour nel mondo dello sviluppo software, ma è uno dei più importanti. E quando fatto bene, è anche uno dei più soddisfacenti.
Hai lo stesso problema in azienda?
Raccontami cosa non va e da quando. Guardo la situazione con te prima di proporre qualsiasi intervento.
Servizio collegato: Gestionale su misura ed ERP per PMI
Ricevi il prossimo articolo
Una mail per ogni articolo nuovo, nient'altro. Ti disiscrivi con un clic dal link in fondo a ogni email.