Gestionali custom su PHP vecchio: stimare tempi e costi della migrazione

Quali fattori determinano tempi e costi della migrazione di un gestionale custom su PHP fuori supporto, come misurarli sul codice, come usare la stima a tre punti per esprimere l’incertezza e cosa deve contenere un preventivo serio.

Copertina con il logo php∞, la categoria Framework e codice custom, il titolo Gestionali custom: tempi e costi e il numero 45

Un gestionale scritto su misura in PHP è spesso il sistema più importante di un’azienda e anche quello meno documentato. Gestisce ordini, magazzino, fatture, rapporti con i clienti; è stato sviluppato in anni diversi da persone diverse, gira su una versione di PHP fuori supporto da tempo e nessuno sa dire con precisione quanto costerebbe portarlo su PHP 8. Quando arriva il momento di chiedere un preventivo, le cifre ricevute possono differire di molto tra un fornitore e l’altro, e nessuna delle due parti sa davvero spiegare perché.

In questo articolo non diamo cifre, perché qualunque numero senza l’analisi del codice sarebbe inventato. Spieghiamo invece quali fattori determinano tempi e costi, come si misurano, quale metodo di stima usiamo per esprimere l’incertezza in modo onesto e quali rischi fanno saltare più spesso i preventivi. Alla fine trovi le domande con cui leggere una proposta, la nostra o quella di un altro fornitore.

Perché le stime a occhio falliscono

La stima più comune nasce così: si guarda il numero di file o di righe, lo si confronta con un progetto simile e si applica un coefficiente. Funziona male per due motivi. Il primo è che la quantità di codice dice poco sul lavoro da fare: diecimila righe scritte con PDO e classi ordinate migrano in fretta, mille righe che usano mysql_* in ogni pagina e concatenano query a mano richiedono molto più tempo. Il secondo è che una parte importante del lavoro non sta nel codice: sta nelle integrazioni, nei dati e nelle regole che solo chi usa il gestionale conosce.

Una stima utile deve quindi separare ciò che si può misurare da ciò che si può solo scoprire, e dichiarare l’incertezza invece di nasconderla in un numero unico.

I fattori che contano

Due colonne di schede con i fattori che determinano tempi e costi della migrazione. A sinistra, in viola, i fattori che si misurano sul codice: dimensione e struttura, cioè file, righe, duplicazioni e codice morto; distanza tra le versioni, da PHP 5.x o 7.x fino a PHP 8.x; funzioni rimosse come mysql_*, ereg, each() e create_function(); librerie ed estensioni copiate a mano, abbandonate o da sostituire. Sotto, la nota che determinano soprattutto la dimensione del lavoro. A destra, in rosso, i fattori che si scoprono con le persone: regole non documentate, cioè calcoli, eccezioni e casi storici; integrazioni e cron con banche, corrieri, SdI e file scambiati; dati e codifiche come latin1 e utf8, date e modalità SQL; test e ambienti, cioè chi collauda, con quali dati e dove. Sotto, la nota che determinano soprattutto l’incertezza della stima
Il codice dice quanto lavoro c’è; le persone dicono quanto è incerta la stima.

Quello che si misura sul codice

  • Distanza tra le versioni. Da PHP 7.4 a PHP 8 cambiano soprattutto il comportamento di alcune funzioni, i confronti tra stringhe e numeri e la gestione degli errori. Da PHP 5.x il salto comprende anche la rimozione delle estensioni mysql ed ereg in PHP 7.0, e quella di each() e create_function() in PHP 8.0.
  • Densità dei problemi. Conta quante occorrenze ci sono e soprattutto quanto sono sparse: una funzione deprecata chiamata in un solo punto si corregge una volta, la stessa funzione copiata in duecento pagine richiede duecento correzioni e duecento verifiche.
  • Librerie ed estensioni. Ogni libreria inclusa a mano va identificata, confrontata con l’originale e aggiornata o sostituita. Lo stesso vale per estensioni PHP non più disponibili.
  • Struttura. Logica, HTML e query mescolati nello stesso file rendono più costose sia le correzioni sia i test.

Quello che si scopre con le persone

  • Regole di business non documentate: arrotondamenti, sconti particolari, eccezioni per singoli clienti, calcoli che “funzionano così da sempre”.
  • Integrazioni: scambi di file con banche e corrieri, invio delle fatture elettroniche, sincronizzazioni con un e-commerce, script eseguiti da cron di cui nessuno ricorda l’esistenza.
  • Dati: tabelle in latin1 mescolate a tabelle in utf8, date salvate come testo, query che funzionano solo con modalità SQL permissive. Da MySQL 5.7 la modalità predefinita è più rigorosa e include ONLY_FULL_GROUP_BY, quindi spesso la migrazione di PHP coincide con quella del database.
  • Test e collaudo: chi può verificare che il gestionale si comporti come prima, con quali dati e in quanto tempo.

Misurare prima di stimare

La prima fase di ogni nostro progetto di migrazione è un’analisi del codice reale, con numeri ricavati dagli strumenti. Qualche comando di esempio, da lanciare su una copia del codice:

# Quanti file PHP e quante righe, escluse le librerie di terze parti
find . -name '*.php' -not -path './vendor/*' | wc -l
find . -name '*.php' -not -path './vendor/*' -print0 | xargs -0 cat | wc -l

# In quanti file compaiono funzioni rimosse in PHP 7.0 e 8.0
grep -rlE '\bmysql_[a-z_]+\(' --include='*.php' . | wc -l
grep -rlE '\b(ereg|eregi|split)\(' --include='*.php' . | wc -l
grep -rlE '\b(each|create_function)\(' --include='*.php' . | wc -l

# Analisi di compatibilità con PHPCompatibility (dalla 8.0 in poi);
# la copertura delle versioni più recenti dipende dalla versione installata
vendor/bin/phpcs -p --extensions=php --standard=PHPCompatibility \
  --runtime-set testVersion 8.0- --report=summary .

Il report riassuntivo dice quanti errori e avvisi ci sono e in quali file si concentrano. Integrato con PHPStan e con una prova di Rector su una parte del codice, permette di separare le correzioni automatizzabili da quelle manuali. Abbiamo descritto gli strumenti nell’articolo su analisi statica con PHPCompatibility, PHPStan e Rector.

Accanto all’analisi del codice servono un inventario delle integrazioni (cosa entra, cosa esce, con quale formato e con quale frequenza), una verifica del database e qualche intervista con chi usa il gestionale ogni giorno. Sono loro a sapere quali funzioni sono critiche e quali non vengono aperte da anni.

Il metodo: stima a tre punti per fase

Per esprimere l’incertezza usiamo una tecnica nota e semplice, la stima a tre punti. Per ogni fase del lavoro si indicano tre valori: ottimistico (O), se tutto va come previsto; più probabile (M); pessimistico (P), se si verificano i problemi ragionevolmente prevedibili. La stima della fase si calcola come media pesata (O + 4M + P) / 6, e la differenza tra P e O dice quanto quella fase è incerta.

Le fasi tipiche di una migrazione di un gestionale custom sono queste:

  1. analisi e inventario: codice, integrazioni, dati, ambienti;
  2. adeguamento automatico: le correzioni che strumenti come Rector applicano in modo meccanico, da rivedere comunque;
  3. correzioni manuali: logica, librerie da sostituire, accesso al database;
  4. test e collaudo: test automatici sui flussi critici e verifica da parte degli utenti;
  5. dati e rilascio: conversioni del database, configurazione del server, passaggio in produzione e periodo di stabilizzazione.
Grafico a intervalli con un esempio illustrativo di stima a tre punti in giorni-persona, con valori inventati. Per ogni fase un intervallo va dal valore ottimistico al pessimistico con una tacca sul più probabile: analisi e inventario 3, 5 e 8, stima 5,2; adeguamento automatico 2, 4 e 8, stima 4,3; correzioni manuali 8, 15 e 30, stima 16,3; test e collaudo 6, 10 e 20, stima 11,0; dati e rilascio 2, 4 e 10, stima 4,7. In basso la formula stima uguale a O più 4M più P, diviso 6, con un totale di circa 41,5 giorni-persona, e la nota che i numeri non si riferiscono a un progetto reale e che conta l’ampiezza degli intervalli
Un esempio con numeri inventati: l’intervallo più largo indica dove concentrare l’analisi.

Nell’esempio, costruito con valori di fantasia, le correzioni manuali e il collaudo hanno gli intervalli più ampi. È quello che succede quasi sempre: sono le fasi in cui pesano le regole non documentate e le integrazioni. Il valore della stima a tre punti sta proprio qui. Mostra al committente dove si trova il rischio e indica dove conviene investire in analisi prima di firmare: ogni ora spesa a chiarire un’integrazione riduce l’intervallo della fase di correzione.

Il costo si ricava moltiplicando le stime per la tariffa, ma con un avvertimento: la somma delle stime pesate è un valore centrale e può essere superata. Un preventivo serio indica come vengono gestiti gli scostamenti, per esempio con una quota a corpo per le fasi ben misurate e una a consumo, con un limite concordato, per quelle incerte.

I rischi che fanno saltare i preventivi

Alcuni problemi ricorrono così spesso che vanno cercati esplicitamente in fase di analisi:

  • codice morto e codice vivo confusi: si spende tempo a migrare pagine che nessuno usa, oppure si trascura uno script richiamato una volta l’anno per la chiusura di bilancio;
  • librerie modificate localmente: aggiornare un generatore di PDF o un client di posta cancella correzioni fatte anni fa e mai documentate;
  • comportamenti che cambiano senza errori: in PHP 8 il confronto tra un numero e una stringa non numerica dà un risultato diverso rispetto a PHP 7, e il codice continua a girare producendo esiti diversi;
  • dati e codifiche: caratteri accentati che si corrompono nella conversione, date non valide rifiutate dalle modalità SQL rigorose;
  • ambiente: percorsi assoluti, configurazioni di php.ini date per scontate, invio di posta tramite il server locale;
  • collaudo sottodimensionato: se gli utenti non hanno tempo di verificare, i problemi emergono in produzione, quando costano di più.

Come ridurre l’incertezza prima di firmare

Il modo più efficace per ridurre l’intervallo di una stima è comprare informazioni prima di comprare il lavoro. In pratica:

  • un’analisi iniziale a sé stante, con un risultato concreto (report, elenco dei problemi, stima per fase) utilizzabile anche con un altro fornitore;
  • una migrazione pilota su un modulo rappresentativo, che misura la velocità reale e fa emergere i problemi tipici del progetto;
  • test di caratterizzazione sui flussi critici prima delle modifiche, così che il collaudo diventi in parte automatico;
  • una migrazione per moduli, quando l’architettura lo permette, invece di un unico passaggio finale.

Se il gestionale è esposto e la migrazione richiede mesi, nel frattempo va protetta la produzione. Il backport delle patch di sicurezza sul ramo di PHP in uso copre questo intervallo senza toccare l’applicazione; ne confrontiamo costi e tempi nell’articolo backport o migrazione.

Cosa deve contenere un preventivo

Un preventivo di migrazione va giudicato anche da come tratta l’incertezza. Prima di confrontare due proposte, verifica che entrambe rispondano a queste domande:

  1. su quale analisi si basa la stima, e se l’analisi è stata fatta sul codice reale;
  2. quale versione di PHP e di database sarà il punto di arrivo, e su quale sistema operativo;
  3. cosa è incluso e cosa è escluso: librerie da sostituire, conversione dei dati, nuove funzioni;
  4. quali ipotesi sono state fatte su integrazioni e collaudo, e cosa succede se si rivelano false;
  5. come vengono gestiti gli scostamenti e chi li approva;
  6. quali test vengono consegnati insieme al codice migrato;
  7. come si torna indietro se il rilascio in produzione non va a buon fine.

Una proposta che dà un prezzo fisso senza aver visto il codice sta scaricando il rischio da qualche parte: in esclusioni scritte in piccolo, in un collaudo ridotto o in una qualità più bassa del previsto.

Conclusioni

Tempi e costi della migrazione di un gestionale custom su PHP vecchio dipendono da due gruppi di fattori. Quelli misurabili sul codice, cioè distanza tra le versioni, densità delle funzioni rimosse, librerie e struttura, determinano la dimensione del lavoro. Quelli che si scoprono con le persone, cioè regole non documentate, integrazioni, dati e collaudo, determinano l’incertezza. Una stima affidabile parte da un’analisi del codice reale con strumenti come PHPCompatibility, esprime ogni fase con tre valori e rende visibile dove si concentra il rischio. Un’analisi iniziale, un modulo pilota e i test di caratterizzazione riducono l’incertezza prima di firmare, mentre il backport delle patch protegge la produzione durante i lavori. Se vuoi partire dall’analisi del tuo gestionale, scrivici.

IL PROSSIMO PASSO

Mettiamo
in sicurezza.

Indicaci versione di PHP, sistema operativo e cosa ti preoccupa. Ti risponderemo con una valutazione dell’esposizione e una proposta di intervento.

Richiedi supporto

Ti porta al modulo di richiesta, in quattro passi.

PHP LEGACY · MANAGED SERVER S.R.L.info@phplegacy.it +39 02 5656 9681

Lunedì – venerdì · 09:30 – 19:30

Urgenza in corso? Reperibilità H24
+39 340 985 4556 ↗