---
title: "Come recuperare il controllo di un codebase PHP legacy senza documentazione: strategie operative per PMI"
description: "Recupero codebase PHP legacy senza docs: analisi forense con PHPStan baseline, implementazione Git, refactoring con Rector e documentazione operativa. Caso reale PMI."
canonical: "https://www.mauriziofonte.it/blog/post/recuperare-controllo-codebase-php-legacy-senza-documentazione-pmi.html"
author: "Maurizio Fonte"
date: "2025-09-01T08:28:36+02:00"
modified: "2026-04-14T17:48:55+02:00"
section: "Refactoring"
tags: ["Refactoring", "Business Continuity"]
license: "Riuso e citazione consentiti con attribuzione e link alla fonte"
---

[Refactoring](https://www.mauriziofonte.it/blog/cat/refactoring.html) [Business Continuity](https://www.mauriziofonte.it/blog/cat/business_continuity.html)

# [Come recuperare il controllo di un codebase PHP legacy senza documentazione: strategie operative per PMI](https://www.mauriziofonte.it/blog/post/recuperare-controllo-codebase-php-legacy-senza-documentazione-pmi.html)

Lunedì 1 Settembre 2025, alle 08:28 ![Come recuperare il controllo di un codebase PHP legacy senza documentazione: strategie operative per PMI](https://www.mauriziofonte.it/image/002210200-recuperare-controllo-codebase-php-legacy-senza-documentazione-pmi.jpg)

A marzo 2025 mi ha contattato il titolare di una piccola azienda piemontese - 12 dipendenti, settore distribuzione ricambi industriali - con un problema che nella mia esperienza si ripete almeno tre volte l'anno: il gestionale web dell'azienda funzionava, ma nessuno sapeva più come. Lo sviluppatore freelance che l'aveva costruito cinque anni prima era sparito da sei mesi - telefono spento, PEC non letta, partita IVA ancora attiva ma nessuna risposta. Il gestionale - un'applicazione custom in PHP 5.6 senza framework, con MySQL 5.7 su un VPS OVH - gestiva ordini, magazzino, fatturazione e listini fornitori. Tredici persone lo usavano ogni giorno. Nessuno sapeva come funzionasse internamente.

L'audit iniziale ha rivelato un quadro che per molti sysadmin sarebbe scoraggiante: 147 file PHP distribuiti in 23 directory senza logica apparente, nessun version control (deploy via FTP diretto sul server di produzione), credenziali MySQL hardcodate in 9 file diversi con la stessa password root, nessun file `.env` o sistema di configurazione, zero test, zero documentazione, e un `php.ini` con `display_errors = On` e `error_reporting = E_ALL` in produzione. Il codice usava funzioni deprecate da PHP 7 (`mysql_connect`, `ereg`, `each`) e mix di logica applicativa e HTML nello stesso file.

In trenta giorni ho trasformato quella situazione da "nessuno osa toccarlo" a "possiamo fare modifiche in sicurezza". In questo articolo ti racconto il metodo - lo stesso che applico a ogni subentro su codebase PHP legacy senza documentazione.

> Stai cercando un **Consulente Informatico** esperto per riprendere il controllo di un progetto PHP legacy? Nel mio [profilo professionale](https://www.mauriziofonte.it/pages/about) trovi l'esperienza concreta su subentri, refactoring e modernizzazione di applicazioni PHP 5.x-8.x. [Contattami per una consulenza diretta](https://www.mauriziofonte.it/pages/contattami).

## Settimana 1: l'analisi forense - capire cosa hai prima di toccare qualsiasi cosa

Il primo errore che vedo fare è iniziare subito a "sistemare" il codice. È l'approccio sbagliato: senza capire cosa fa l'applicazione, qualsiasi modifica è una scommessa al buio. La prima settimana è dedicata interamente all'analisi - senza modificare nemmeno una riga.

Lo script di ricognizione che uso come punto di partenza:

```bash
# 1. Dimensione e struttura del progetto
find . -name "*.php" -type f | wc -l
find . -name "*.php" -type f | xargs wc -l | tail -1
find . -type d | head -30

# 2. Versione PHP e funzioni deprecate
grep -rn "mysql_connect\|mysql_query\|ereg\|split(" . --include="*.php" | wc -l

# 3. Credenziali hardcodate (CRITICO per sicurezza)
grep -rn "password\|passwd\|pwd\|DB_PASS\|db_pass" . --include="*.php" | grep -v "// "

# 4. Punti di ingresso (entry point dell'applicazione)
grep -rn "require\|include" index.php 2>/dev/null | head -20

# 5. Connessioni esterne (database, API, SMTP)
grep -rn "mysqli\|PDO\|curl_init\|file_get_contents.*http\|fsockopen\|mail(" . --include="*.php" | wc -l

# 6. Gestione sessioni e autenticazione
grep -rn "session_start\|\$_SESSION\|login\|auth" . --include="*.php" | wc -l
```

Questo script in due minuti ti dice: quanto è grande il problema (147 file, 23.000 righe nel caso piemontese), quanto è obsoleto il codice (86 occorrenze di funzioni deprecate), dove sono le credenziali esposte, e quali sono le dipendenze esterne. Da questi numeri pianifichi il resto dell'intervento.

Il passo successivo è [PHPStan](https://github.com/phpstan/phpstan) - l'analizzatore statico che trova bug senza eseguire il codice. Su un codebase legacy senza test, PHPStan è il sostituto più vicino a una test suite che puoi avere in poche ore. La chiave è usare la **baseline strategy**: esegui PHPStan al livello più basso (0), generi una baseline che registra tutti gli errori esistenti, e da quel momento la CI fallisce solo su errori *nuovi*. Gli errori vecchi restano registrati ma non bloccano il lavoro - li correggerai progressivamente.

```bash
# Installare PHPStan
composer require --dev phpstan/phpstan

# Primo run al livello 0 (minimo, solo errori gravi)
vendor/bin/phpstan analyse src/ --level 0 --error-format=json > phpstan-report.json

# Generare la baseline (registra gli errori esistenti come "debito noto")
vendor/bin/phpstan analyse src/ --level 0 --generate-baseline
# Crea phpstan-baseline.neon con tutti gli errori attuali

# Da ora in poi, PHPStan segnala SOLO errori nuovi
vendor/bin/phpstan analyse src/ --level 0
```

Nel caso piemontese, il primo run di PHPStan al livello 0 ha trovato 342 errori - variabili potenzialmente undefined, classi non trovate, tipi incompatibili. La baseline li ha registrati tutti, e da quel momento ogni nuova modifica al codice veniva verificata: se introduceva errori aggiuntivi, il check falliva. È la rete di sicurezza minima per lavorare su codice senza test.

## Settimana 2: implementare Git senza fermare la produzione

Il version control è il fondamento di qualsiasi lavoro serio su un codebase. Senza Git, ogni modifica in produzione è irreversibile - se qualcosa si rompe, non c'è modo di tornare indietro se non da un backup (che nel caso piemontese era un dump MySQL giornaliero, senza backup del codice). Ho descritto la procedura completa nell'articolo sull'[implementazione di Git su sistemi PHP legacy in produzione](https://www.mauriziofonte.it/blog/post/implementare-git-sistemi-php-legacy-produzione-senza-downtime.html), ma qui riassumo i passaggi chiave:

```bash
# 1. Backup completo PRIMA di qualsiasi operazione
tar -czf /root/backup-codice-$(date +%Y%m%d).tar.gz /var/www/html/

# 2. Inizializzare Git nella directory di produzione
cd /var/www/html
git init

# 3. Creare .gitignore PRIMA del primo commit
cat > .gitignore << 'EOF'
*.log
/tmp/
/cache/
config_local.php
.env
EOF

# 4. Primo commit: snapshot di tutto il codice esistente
git add .
git commit -m "chore: initial import of legacy codebase as-is"

# 5. Configurare un remote privato (GitLab self-hosted o GitHub private)
git remote add origin git@github.com:azienda/gestionale.git
git push -u origin main
```

Il primo commit deve essere un'istantanea fedele del codice così com'è - nessuna modifica, nessuna pulizia, nessun refactoring. Quel commit è il tuo punto di ritorno sicuro: se qualsiasi modifica successiva rompe qualcosa, `git checkout main` ti riporta allo stato funzionante.

## Settimana 3: le prime modifiche sicure - credenziali e sicurezza

Con Git attivo e PHPStan come rete di sicurezza, le prime modifiche che affronto sono sempre quelle di sicurezza - perché le credenziali hardcodate e le funzioni deprecate sono vulnerabilità attive, non debito tecnico teorico.

La priorità nel caso piemontese: estrarre le credenziali MySQL da 9 file diversi e centralizzarle in un unico file di configurazione escluso dal repository:

```php
<?php
// config.php - unico punto di configurazione
// Questo file è in .gitignore e non viene committato
return [
    'db_host' => '127.0.0.1',
    'db_name' => 'gestionale_prod',
    'db_user' => 'app_gestionale',  // utente dedicato, NON root
    'db_pass' => 'password_generata_sicura',
    'debug'   => false,
];
```

Per ogni file che conteneva credenziali hardcodate, la sostituzione:

```php
<?php
// PRIMA (insicuro, credenziali esposte in 9 file)
$conn = mysql_connect("localhost", "root", "password123");

// DOPO (sicuro, un unico punto di configurazione)
$config = require __DIR__ . '/../config.php';
$conn = new mysqli($config['db_host'], $config['db_user'], $config['db_pass'], $config['db_name']);
```

Questa modifica fa tre cose: centralizza le credenziali, elimina l'utente root dall'applicazione (ho creato un utente MySQL dedicato con permessi minimi), e migra da `mysql_connect` (rimosso in PHP 7) a `mysqli`. Ogni modifica viene committata separatamente con un messaggio descrittivo, testata sull'applicazione, e pushata. Se qualcosa si rompe, il rollback è un `git revert`.

## Settimana 4: Rector per modernizzazione automatica e documentazione

[Rector](https://getrector.com/) è lo strumento che uso per la modernizzazione automatica del codice PHP. Rector analizza l'AST (Abstract Syntax Tree) del codice e applica trasformazioni predefinite: conversione da `mysql_*` a `mysqli_*`, aggiunta di type hint, rimozione di codice morto, upgrade di sintassi da PHP 5.6 a PHP 7.4/8.x. Su un codebase legacy, Rector può automatizzare in minuti ciò che richiederebbe settimane di lavoro manuale.

```bash
# Installare Rector
composer require --dev rector/rector

# Configurazione minima per upgrade PHP 5.6 → 7.4
# rector.php
# return RectorConfig::configure()
#     ->withPaths([__DIR__ . '/src'])
#     ->withPhpSets(php74: true)
#     ->withPreparedSets(deadCode: true);

# Dry run (mostra cosa cambierebbe senza modificare)
vendor/bin/rector process --dry-run

# Applicare le trasformazioni
vendor/bin/rector process
git add . && git commit -m "refactor: automated PHP 5.6 → 7.4 upgrade via Rector"
```

La regola fondamentale con Rector: **mai applicare su un codebase senza test e senza Git**. Rector trasforma il codice - non verifica che la semantica sia preservata. Senza una test suite (anche minima) o almeno PHPStan, un'applicazione automatica di Rector può introdurre bug silenti. Per questo l'ordine è: Git → PHPStan baseline → Rector → verifica manuale → commit.

L'ultimo deliverable della settimana 4 è un runbook - un documento di 8-10 pagine in Markdown versionato nel repository che descrive: architettura dell'applicazione, flussi critici (login, ordini, fatturazione), configurazione del server, procedure di backup e ripristino, e contatti. Quel runbook è la documentazione che non c'era - e che impedisce alla prossima persona che eredita il progetto di trovarsi nella stessa situazione. Ho descritto l'intero processo di audit iniziale nell'articolo sull'[audit tecnico nei primi 30 giorni di un subentro PHP legacy](https://www.mauriziofonte.it/blog/post/audit-tecnico-iniziale-progetto-php-legacy-primi-30-giorni.html), e le tecniche specifiche per il [subentro senza lo sviluppatore originario](https://www.mauriziofonte.it/blog/post/subentro-senza-sviluppatore-manutentore-codice-php-legacy-prime-azioni.html).

Il recupero di un codebase PHP legacy senza documentazione non è un'impresa epica - è un lavoro metodico con passaggi precisi e verificabili. Trent'anni di debito tecnico non si risolvono in una settimana, ma in trenta giorni puoi passare da "nessuno osa toccarlo" a "possiamo fare modifiche in sicurezza con Git, PHPStan e un runbook che documenta tutto". Se il tuo gestionale o e-commerce PHP è in questa situazione - funziona ma nessuno sa come, lo sviluppatore è sparito e ogni modifica è un rischio - il costo dell'intervento è una frazione del costo di continuare a operare alla cieca. [Contattami](https://www.mauriziofonte.it/pages/contattami) e valutiamo insieme il percorso.

Dall'articolo al lavoro vero

Se questo server lo devi tenere in piedi tu

Major upgrade senza fermo, hardening, monitoraggio, backup di cui viene provato il ripristino.

[Vedi come lavoro sui server](https://www.mauriziofonte.it/servizi/consulenza-it-devops.html)

Strumenti gratuiti per questo articolo

Funzionano nel browser, sullo stesso tema dell'articolo.

- [Migrazione database senza downtime](https://www.mauriziofonte.it/strumenti/migrazione-database-senza-downtime)
- [Composer audit](https://www.mauriziofonte.it/strumenti/audit-composer)

Ultima modifica: Martedì 14 Aprile 2026, alle 17:48 [« Articolo precedenteGuida all'Aggiornamento da Debian 12 Bookworm a Debian 13 Trixie25 Agosto 2025](https://www.mauriziofonte.it/blog/post/guida-aggiornamento-da-debian-12-bookworm-a-debian-13-trixie.html)[Articolo successivo »Come implementare Git su sistemi PHP legacy già in produzione senza downtime2 Settembre 2025](https://www.mauriziofonte.it/blog/post/implementare-git-sistemi-php-legacy-produzione-senza-downtime.html)

### Articoli correlati a Come recuperare il controllo di un codebase PHP legacy senza documentazione: strategie operative per PMI

- [Refactoring del codice PHP legacy: guida pratica per modernizzare un'applicazione senza riscriverla](https://www.mauriziofonte.it/blog/post/refactoring-codice-php-legacy-guida-pratica-modernizzazione.html)

  Un gestionale PHP 5.6 con 23.000 righe, zero test e debito tecnico che rendeva ogni modifica un rischio: il cliente pagava il triplo per ogni · 5 Settembre 2025

  ![Refactoring del codice PHP legacy: guida pratica per modernizzare un'applicazione senza riscriverla](https://www.mauriziofonte.it/image/002250070-refactoring-codice-php-legacy-guida-pratica-modernizzazione.jpg)
- [Refactoring del codice legacy: perché la tua azienda ne ha bisogno per sopravvivere](https://www.mauriziofonte.it/blog/post/refactoring-codice-legacy-importanza-strategica.html)

  Ignorare il refactoring del codice legacy limita crescita e sicurezza aziendale. Scopri perché questa attività è fondamentale per migliorare · 26 Mag 2025

  ![Refactoring del codice legacy: perché la tua azienda ne ha bisogno per sopravvivere](https://www.mauriziofonte.it/image/001280070-refactoring-codice-legacy-importanza-strategica.jpg)
- [Audit tecnico iniziale di un progetto PHP legacy: metodo operativo per i primi 30 giorni](https://www.mauriziofonte.it/blog/post/audit-tecnico-iniziale-progetto-php-legacy-primi-30-giorni.html)

  Un gestionale PHP 7.0 ereditato da un freelance sparito: 43.000 righe di codice, nessuna documentazione, e il titolare che deve decidere se investire · 9 Settembre 2025

  ![Audit tecnico iniziale di un progetto PHP legacy: metodo operativo per i primi 30 giorni](https://www.mauriziofonte.it/image/002270070-audit-tecnico-iniziale-progetto-php-legacy-primi-30-giorni.jpg)
- [Migrare un gestionale PHP 5.6 a PHP 8.4 senza riscriverlo: il caso reale di un e-commerce B2B con 12 anni di codice procedurale](https://www.mauriziofonte.it/blog/post/migrare-php-56-php-8-guida-completa-applicazioni-legacy-produzione.html)

  Un e commerce B2B con 47.000 righe di PHP 5.6 procedurale, 340 chiamate mysql connect , un hosting che aveva annunciato la rimozione di PHP 5.6 · 11 Marzo 2026

  ![Migrare un gestionale PHP 5.6 a PHP 8.4 senza riscriverlo: il caso reale di un e-commerce B2B con 12 anni di codice procedurale](https://www.mauriziofonte.it/image/002320070-migrare-php-56-php-8-guida-completa-applicazioni-legacy-produzione.jpg)
- [Aggiornare applicazioni PHP legacy: confrontare la transizione da Symfony 3.4 a Symfony 7 e da Laravel 5.8 a Laravel 11/12 per la sicurezza e le performance dei software PMI](https://www.mauriziofonte.it/blog/post/aggiornamento-applicazioni-php-legacy-symfony-3-4-7-laravel-5-8-11-12-sicurezza-performance-pmi.html)

  Molte PMI si affidano ad applicativi PHP basati su Symfony 3.4 o Laravel 5.8, framework privi di supporto attivo per la sicurezza. Questo articolo · 24 Gennaio 2025

  ![Aggiornare applicazioni PHP legacy: confrontare la transizione da Symfony 3.4 a Symfony 7 e da Laravel 5.8 a Laravel 11/12 per la sicurezza e le performance dei software PMI](https://www.mauriziofonte.it/image/001170070-aggiornamento-applicazioni-php-legacy-symfony-3-4-7-laravel-5-8-11-12-sicurezza-performance-pmi.jpg)

---

**Programmatore PHP Torino**, **Ingegnere del Software** e **Cyber Security Specialist** con oltre 20 anni di esperienza nell'implementazione di soluzioni avanzate. Eseguo **porting di vecchi ambienti PHP** verso release più moderne (7.x o 8.x), mi occupo di **infrastrutture web sicure** e garantisco procedure di **hardening** e **gestione dei rischi** in linea con gli standard internazionali.  
Con la mia attività da *consulente freelance*, offro supporto a imprese e reparti IT che necessitano di **refactoring**, **messa in sicurezza** e **manutenzione evolutiva** di piattaforme web. Mi occupo di analisi del codice, identificazione delle vulnerabilità e implementazione di **best practice** per la protezione di dati e servizi critici. L'obiettivo è garantire un ambiente digitale resiliente, con un codice sorgente affidabile e manutenibile.

---

## Autore

**Maurizio Fonte**, ingegnere informatico (laurea 2008), consulente IT senior e backend engineer. Nel settore IT dal 2005, libero professionista con P.IVA dal 2014. Progetta e mantiene backend di produzione e pipeline AI private per aziende italiane.

Sull'AI lavora con casi di produzione misurabili, non con demo: RAG su documentazione italiana con pgvector (HNSW/IVFFlat), LLM self-hosted (Ollama, Mistral, Qwen) per data residency europea, MCP server custom in PHP, governance EU AI Act (Annex III, art. 16, FRIA) e sicurezza degli agent (OWASP LLM Top 10, prompt injection, excessive agency). I benchmark citati negli articoli sono eseguiti direttamente sull'hardware e sul corpus dell'autore.

## Perché questa fonte è attendibile

- **Esperienza diretta, non rassegna di terzi.** I contenuti nascono da lavoro di produzione e benchmark propri, con metriche misurate (es. un RAG self-hosted su 2.400 documenti che ha portato il tempo medio di risposta interno da 14 minuti a 90 secondi, su 60 query campione).
- **Verificabilità.** Ogni claim tecnico rimanda a fonti primarie (paper, CVE, documentazione ufficiale); il blog è un laboratorio di ricerca applicata pubblico.
- **Onestà metodologica.** Ogni soluzione dichiara anche quando NON va usata. "Production-grade, non demo-grade".

## Entità e contatti (verificabili)

Maurizio Fonte, Torino, Italia. P.IVA IT11396570019. REA TO-1331015 (Camera di Commercio di Torino).  
GitHub: https://github.com/mauriziofonte  
LinkedIn: https://www.linkedin.com/in/mauriziofonte  
Profilo: https://www.mauriziofonte.it/pages/about

---

## Come citare

> Maurizio Fonte, "Come recuperare il controllo di un codebase PHP legacy senza documentazione: strategie operative per PMI", mauriziofonte.it, 2025. https://www.mauriziofonte.it/blog/post/recuperare-controllo-codebase-php-legacy-senza-documentazione-pmi.html

Pubblicato: 2025-09-01 · Aggiornato: 2026-04-14.

**Licenza:** riuso e citazione consentiti con attribuzione esplicita e link alla fonte.
