Il codice legacy non si riscrive: si mette sotto PHPStan e test, un livello alla volta, mentre continua a rilasciare
Per software house con un gestionale PHP o Laravel di dieci anni, dove nessuno osa più toccare certe cartelle. Il debito tecnico si riduce con numeri che possono solo migliorare, non con un mese di stop.
Ti riconosci in almeno due di queste?
Rispondi a mente, senza dirlo a nessuno.
- C'è una cartella che "funziona, meglio non toccare", e ogni nuovo assunto la scopre da solo.
- Un errore di tipo (null dove serviva un oggetto) arriva in produzione una volta al mese.
- I test ci sono, ma nessuno sa quali passano davvero; la CI è rossa da settimane e nessuno la guarda più.
- Avete provato PHPStan: 4.000 errori al primo giro, e il tentativo è finito lì.
- Il cliente chiede la conformità NIS2 e la prima domanda è "chi ha toccato questo file, e quando?".
Se hai detto sì almeno due volte, il problema non sono gli sviluppatori: è che manca una rete di sicurezza che cresca da sola.
Quanto costa davvero il debito tecnico?
Fai il conto sulla tua software house.
- Un bug di tipo in produzione al mese: mezza giornata per trovarlo, mezza per correggerlo, un cliente per assorbirlo. Dodici l'anno.
- Ogni sviluppatore nuovo che impara "cosa non toccare" per prova ed errore: settimane di onboarding che un'analisi statica ridurrebbe a giorni.
- Una CI rossa ignorata è una CI che non esiste: tutto il tempo speso a scriverla è perso.
- La riscrittura completa costa i mesi di riscrittura più i mesi in cui il vecchio resta senza rete.
Come si porta PHPStan su codice legacy senza fermarsi?
- Livello basso più baseline: PHPStan parte al livello che passa e mette gli errori esistenti in un file di baseline. Da quel momento la CI blocca solo gli errori nuovi. Nella repo di questo sito: 350.000 righe, livello 3, un baseline di 796 errori che può solo calare.
- Perimetri al massimo: i moduli nuovi e quelli più delicati (pagamenti, accessi, SEO) girano a livello massimo senza baseline, con copertura 100%. Il resto sale di un livello al mese.
- Test di caratterizzazione prima di toccare il legacy: descrivono cosa fa il codice oggi, giusto o sbagliato che sia, così la correzione non cambia il comportamento per sbaglio.
- Mutation testing sul perimetro: Infection cambia il codice di proposito e controlla che i test se ne accorgano; un test che non fallisce mai non protegge.
- Larastan per Laravel: capisce Eloquent, le relazioni e i facade, e toglie i falsi positivi che avevano fatto abbandonare PHPStan la prima volta.
Cosa trovate nella CI dopo il primo mese?
- PHPStan verde a ogni push, con un baseline che nel mese è sceso e non può risalire.
- I test che contano (quelli del perimetro) al 100% di copertura e con un punteggio di mutation testing minimo.
- Un elenco scritto delle cartelle "da non toccare", ora con test di caratterizzazione: si possono toccare.
- Per la NIS2 lato software: chi ha cambiato cosa e quando, per ogni file, con la CI a testimone. La pagina NIS2 e penetration test lato codice spiega il resto, con la scadenza del 31 ottobre 2026.
Chi lo fa, e perché ti puoi fidare
Quattordici anni di PHP e Laravel in cinque software house (fintech, privacy, viaggi, pubblica amministrazione), gli ultimi sei da tech lead; JavaScream open source e articoli su Red Hot Cyber sulla sicurezza applicativa. Il metodo è lo stesso scritto in una proposta europea valutata 12,3 su 15: TDD con copertura 100% sui moduli nuovi, PHPStan al livello massimo, mutation testing. Entro nel vostro repository lunedì, con la vostra pipeline.
Quanto costa?
A giornate, con tariffe di mercato (Assintel Report 2025: media 508 € al giorno per i freelance ICT in Italia, profili senior sopra): da 500 a 650 € al giorno per un senior Laravel nel vostro team, da 600 a 750 € per sicurezza applicativa e penetration test con report. La prima settimana è a giornate e si può fermare: se dopo cinque giorni non vedete numeri migliori, avete comunque il report. Il listino completo e la pagina senior Laravel per software house.
Il passo giusto è piccolo: 30 minuti gratuiti con accesso in lettura al repository o a un log di una giornata. Ne esce un documento con i tre punti da cui partire, vostro anche se non proseguite.