Ogni linguaggio presenta un divario tra ciò che è corretto oggi e ciò di cui si è scritto di più. Per PHP questo divario è insolitamente ampio, perché il linguaggio è cambiato profondamente tra la versione 5.x e la 8.x, mentre online sono rimasti tutti i tutorial pubblicati nel frattempo.
La conseguenza per lo sviluppo assistito dall'AI è specifica e prevedibile: il PHP generato tende verso le pratiche dell'epoca più documentata, che non è quella in cui si lavora oggi. L'output appare convenzionale — ed è proprio questo il problema — e talvolta incorpora assunzioni che non sono più sicure da diverse versioni.
Non è un argomento contro l'uso di questi strumenti. È un invito a sapere cosa cercare, che in PHP è una lista breve e stabile.
Perché Proprio PHP
Tre fattori si sommano.
- La quantità di materiale obsoleto è enorme. PHP è stato il linguaggio web di riferimento per oltre un decennio, periodo in cui sono stati scritti un numero enorme di tutorial, risposte nei forum e articoli — la maggior parte mai aggiornata.
- Il linguaggio è cambiato più di altri. Tipi scalari, tipi di ritorno, enum, proprietà readonly, promozione dei costruttori, callable di prima classe e un modello di gestione degli errori molto più rigoroso sono arrivati dopo che la maggior parte di quel materiale era già stato scritto.
- Il vecchio codice funziona ancora. A differenza di altri linguaggi in cui una release bloccante ha forzato l'evoluzione dell'ecosistema, molto codice dell'era PHP 5 viene ancora eseguito oggi, mantenendo le vecchie pratiche sia nei materiali attuali che in quelli storici.
Il risultato è una distribuzione sbilanciata verso schemi sintatticamente validi, subito eseguibili, ma non più raccomandati per scrivere PHP.
Pattern da Monitorare
1. Query Costruite con Stringhe
Il caso più rilevante. Per anni i tutorial hanno mostrato l'accesso al database concatenando variabili in una stringa di query, e questo schema è molto rappresentato. Il codice generato spesso usa correttamente un query builder, ma poi ricorre all'interpolazione diretta di stringhe per i casi in cui il builder è meno comodo — un ORDER BY dinamico, una lista di colonne calcolate, una clausola IN.
Funziona, supera i test, ma è un vettore di injection. Ogni query grezza nel codice generato va revisionata come se fosse stata scritta da uno sconosciuto, perché di fatto lo è.
2. Confronti Deboli e Conversioni di Tipo
PHP 8 ha risolto i peggiori comportamenti di confronto tra stringhe e numeri, ma il codice generato continua a usare == dove servirebbe ===, soprattutto nei controlli di autenticazione e autorizzazione, dove le conseguenze sono più gravi. Nei materiali vecchi il confronto debole era usato liberamente perché di solito funzionava.
3. Escape Manuale invece delle Funzionalità del Framework
Escape manuale, impostazione diretta degli header, funzioni di sanitizzazione personalizzate. Queste pratiche erano necessarie prima dei framework e ora rischiano di aggirare protezioni già offerte dal framework. Se il codice generato esegue l'escape in autonomia in una base di codice dove il template già lo fa, è un segnale che il modello ha ripreso una pratica superata.
4. Crittografia e Gestione Password Obsolete
Qualsiasi cosa riguardi hashing, token o casualità richiede particolare attenzione. I materiali vecchi mostrano approcci che erano consigliati all'epoca e oggi sono sbagliati. Il PHP moderno offre strumenti corretti e semplici per tutto questo; il codice generato non li adotta sempre.
5. Accesso ai Superglobali non Validato
Leggere i dati della richiesta direttamente e usarli senza validazione, in un framework che offre un layer di validazione. Questo schema è il segnale più affidabile che l'output deriva da materiale pre-framework.
6. Signature Senza Tipi
Non è una vulnerabilità, ma una lenta erosione. Il codice generato spesso omette i tipi di parametro e di ritorno, e ogni omissione elimina un controllo che l'analisi statica avrebbe potuto eseguire. Su qualche centinaio di funzioni generate, una base di codice perde copertura tipizzata senza che nessuna singola modifica sembri sbagliata.
Perché Sfugge alla Revisione
Il problema non è che il codice sembri sospetto. È che appare ordinario.
- È stilisticamente coerente. Il codice generato è convenzionale per costruzione, il che rende più difficile per chi revisiona individuare anomalie.
- Funziona. Il comportamento è corretto per i dati di input usati dal programmatore nei test.
- Chi revisiona guarda una diff, non un progetto. Un rischio di injection in un metodo di quindici righe appare come quindici righe ordinarie.
- Il volume supera l'attenzione. Si produce più codice per ora di revisione rispetto al passato, e la qualità della revisione cala all'aumentare della quantità, come prevedibile.
Il rischio si amplifica: è massimo sulle basi di codice obsolete, che sono proprio quelle dove si ricorre di più all'AI, perché il codice è poco familiare. Il modello produce codice plausibile in stile legacy che si integra perfettamente con il contesto, senza che nulla sembri fuori posto.
Come Difendersi
Quasi tutto questo è rilevabile automaticamente, quindi la difesa dovrebbe essere automatica e non affidata solo all'attenzione del revisore.
- Analisi statica avanzata, con blocco in CI. PHPStan o Psalm rilevano tipi mancanti, assunzioni non sicure e buona parte dei problemi di confronto debole prima che il codice sia visto da una persona.
- Un ruleset di taint-analysis o orientato alla sicurezza, progettato per individuare lo schema delle query costruite tramite stringhe.
- declare(strict_types=1) ovunque, così che i problemi di conversione dei tipi emergano subito e non silenziosamente.
- Scansione delle dipendenze e delle vulnerabilità in CI, perché il codice generato può suggerire pacchetti abbandonati o versioni note come vulnerabili.
- Una checklist breve per il codice generato — query grezze, confronti nei percorsi di autenticazione, elementi crittografici, accesso diretto ai dati della richiesta.
- Un secondo revisore per i cambiamenti sui confini di sicurezza, indipendentemente da chi o cosa li ha scritti.
E la soluzione strutturale, che porta vantaggi su tutto il resto: aggiornare la base di codice. Una versione moderna di PHP con tipi stretti, un framework mantenuto e un'alta copertura di analisi statica riduce drasticamente lo spazio per codice plausibile ma errato, perché la maggior parte delle vecchie pratiche non compila, non supera l'analisi o fallisce in modo evidente.
È lo stesso argomento che portiamo sulla leggibilità del codice nella policy di revisione Laravel assistita da AI, ed è un altro motivo per cui la questione della versione in PHP è ancora la scelta giusta conta più della scelta del linguaggio.
La Posizione di Governance
Per un CTO o VP of Engineering che deve sostenere una posizione su questo tema:
- Non lo vieti. I team usano comunque questi strumenti, e un divieto sostituisce una pratica verificabile con una non dichiarata.
- Richieda la dichiarazione, così chi revisiona sa quali diff richiedono la checklist.
- Automatizzi dove possibile. Ogni regola che passa da un documento a un job CI non dipende più dall’attenzione umana.
- Lasci sempre l’elemento umano sui confini di sicurezza. Autenticazione, autorizzazione, pagamenti, dati personali.
- Finanzi la modernizzazione. L’intervento più efficace contro codice generato di bassa qualità è un codebase dove il codice scadente non sopravvive alla toolchain.
Questo è il lavoro che svolgiamo tramite la nostra pratica di sviluppo PHP e la modernizzazione PHP personalizzata; si collega direttamente alla questione più ampia di dove l’AI abbia davvero un ruolo nella delivery — la nostra pratica di integrazione AI e il team di ingegneria AI coprono questo aspetto.
Domande frequenti
Il PHP generato dall’AI può contenere vulnerabilità di sicurezza?
Sì, e le vulnerabilità sono prevedibili: query costruite tramite stringhe, confronti deboli nei percorsi di autenticazione, consigli crittografici obsoleti e dati delle richieste non validati. Tutte derivano dallo stesso problema: una decade di materiale pubblicato prima delle attuali funzionalità di sicurezza di PHP.
Perché questo è più grave in PHP rispetto ad altri linguaggi?
Perché PHP è cambiato più di altri tra la versione 5.x e la 8.x, mantenendo però una grande quantità di materiale mai aggiornato, e molto codice dell’era PHP 5 è ancora in uso. La distribuzione di ciò che è stato scritto è più sbilanciata verso il passato rispetto ad ecosistemi più giovani.
Come individuarlo in fase di revisione?
Non si affidi solo alla revisione — il codice appare normale, proprio ciò che sfugge a chi cerca anomalie. Imponga tipi stretti e livelli elevati di analisi statica in CI, aggiunga un set di regole di sicurezza che rilevi query costruite tramite stringhe e tenga una checklist per i quattro o cinque pattern specifici.
Conviene evitare strumenti di AI per il codice PHP legacy?
No, ma consideri le codebase legacy come casi a rischio più elevato. Il codice generato che si adatta allo stile legacy circostante è il più difficile da individuare, quindi il lavoro di modernizzazione — versione attuale, tipi stretti, analisi statica — è ciò che rende sicuro l’uso dell’AI, non solo rapido.
Vale anche per framework come Laravel e Symfony?
In misura minore, perché le convenzioni dei framework sono forti e ben rappresentate, ma lo stesso problema si manifesta come utilizzo di idiomi di versioni precedenti — helper deprecati, sintassi di validazione superata, pattern sostituiti da funzionalità native. La difesa resta la stessa: imponga le regole nella toolchain.
Affidi il Lavoro alla Toolchain
Impostiamo l’analisi statica, le regole di sicurezza e i gate CI che fanno fallire automaticamente questa classe di problemi, senza dipendere dall’attenzione di chi revisiona. Contatti il nostro team; rispondiamo entro un giorno lavorativo.
