Fare il debug con Xdebug o PHP Debugger, a mano o con un'IA
L'IDE di JumPHP ha un vero debugger passo passo: si ferma il programma su una riga, si guardano le variabili, se ne cambia una e si avanza passo passo. Parla DBGp, il protocollo di Xdebug, e quindi può pilotare due motori:
- Xdebug, il classico (predefinito);
- PHP Debugger, un debugger DBGp più recente, libero e open source, compatibile con le impostazioni di Xdebug, con un sovraccarico quasi nullo.
Si usano allo stesso modo nell'IDE. Puoi anche affidare il debugger a un'IA (Claude Code): mette i punti di interruzione, avvia il programma, legge le variabili e trova da sola il bug.
Quale motore scegliere
| Xdebug | PHP Debugger | |
|---|---|---|
| In JumPHP | predefinito, tutti i runtime | runtime desktop (PHP 8.2 - 8.5) |
| Sovraccarico | PHP è nettamente più lento | «near-zero overhead when idle», sempre attivo, nessun innesco da impostare |
Runtime async (PHP 8.6, runtime: async) |
sì | no: si usa Xdebug al suo posto (lo dice bin/jumphp) |
| IA | il server MCP di JumPHP (bin/jumphp debug) |
il suo server MCP (dbgp mcp), che vede anche l'output dello script e gli avvisi di PHP |
In pratica: PHP Debugger per l'uso quotidiano, le esecuzioni lunghe (un gioco che gira 600 fotogrammi, una suite di test) e il debug con IA. Xdebug se lavori con il runtime async (thread) o ti serve ciò che solo Xdebug fa. Sono intercambiabili nell'IDE: provali sullo stesso progetto.
La pagina di PHP Debugger non dà alcun numero di benchmark: afferma solo un costo quasi nullo finché non si fa debug. Misura sul tuo progetto se la differenza conta.
Scegliere il motore nell'IDE
- Il pulsante Debug dell'intestazione (l'insetto accanto a Run,
Maiusc+F9) apre un menu: Debug con (Xdebug o PHP Debugger, per questa esecuzione) e Motore predefinito (quello che un semplice clic userà da allora). Un clic destro sul pulsante apre lo stesso menu. - La prima esecuzione con un motore costruisce un'immagine Docker una volta (circa un minuto). Le successive partono subito.
- Una notifica avvisa quando il programma non si collega mai al debugger (è terminato prima, o niente dopo 3 minuti). L'output della finestra Run di solito ne dice il motivo.
Scegliere il motore da un terminale
Tutto passa da bin/jumphp, come sempre:
# Xdebug (predefinito)
JUMPHP_XDEBUG=9003 bin/jumphp test pong
# PHP Debugger
JUMPHP_DEBUGGER=php-debugger JUMPHP_XDEBUG=9003 bin/jumphp test pong
JUMPHP_XDEBUG=<porta>attiva il passo passo: PHP si collega a un debugger in ascolto su quella porta del tuo computer (composer, phpstan ephp -lgirano senza).JUMPHP_DEBUGGER=xdebug|php-debuggersceglie il motore (xdebugper default).- Con
php-debugger,bin/jumphpcostruisce una volta l'immaginedocker/desktop-phpdebugger, a partire da quella desktop, che resta senza. - Sul runtime async (PHP 8.6) compare il messaggio «PHP Debugger does not run on PHP 8.6 (async runtime): Xdebug is used» e gira Xdebug.
Fare il debug a mano nell'IDE
- Punto di interruzione: clicca nella barra laterale, a sinistra di una riga PHP. Un clic destro dà una condizione (un'espressione PHP: si ferma solo se è vera, es.
$this->score < 0);Ctrl+F8ne mette uno al cursore. I punti sono salvati per progetto e seguono le righe quando modifichi. - Debug (
Maiusc+F9): il programma gira e si ferma al primo punto. La riga è evidenziata e si apre la finestra Debug. - Guardare: lo stack delle chiamate (clicca un frame per vedere le sue variabili), le variabili ad albero lette su richiesta, i watch e un campo per valutare qualsiasi espressione PHP dove il programma si è fermato.
- Cambiare un valore: doppio clic su una variabile o
F2, scrivi un'espressione PHP (9,"Ada",[1, 2],null) e continua con il nuovo valore. - Avanzare: Riprendi
F9, Passo sopraF8, Passo dentroF7, Passo fuoriMaiusc+F8, Esegui fino al cursoreAlt+F9, Arresta. - Eccezioni: Interrompi alle eccezioni… (l'icona di avviso della finestra Debug):
*o nomi di classe (TypeError,App\GameOver). Si ferma dove l'eccezione è lanciata, catturata o no, e indica quale con il suo messaggio.
Ispettore al passaggio del mouse (nel prossimo aggiornamento dell'IDE): con il programma fermo a un punto di interruzione, passa il mouse su una variabile nell'editor per ottenere un albero espandibile del suo valore, con Copia e Modifica.
Un consiglio per i giochi: fai il debug di esecuzioni senza finestra (test, shot): un gioco fermo in una finestra si blocca finché non riprendi.
Fare il debug con un'IA
Un'IA fa il debug meglio con un debugger che con i var_dump(): legge i valori reali, una domanda alla volta, senza toccare il tuo codice. Esistono due server MCP. Usane uno alla volta (entrambi ascoltano sulla porta 9003).
1. Il server di JumPHP: bin/jumphp debug
Il debugger dell'IDE stesso come server MCP (gira in Docker, con Xdebug):
claude mcp add jumphp-debug -- bin/jumphp debug
I suoi strumenti:
| Strumento | Cosa fa |
|---|---|
debug_breakpoints |
imposta i punti di un file (lines, o {line, condition}), li elenca senza percorso, clear_all |
debug_exceptions |
le eccezioni che fermano il programma (* = tutte, [] = nessuna) |
debug_wait |
attende che il programma si fermi a un punto o a un'eccezione, poi dà dove, lo stack e le variabili |
debug_state |
dove è fermo, lo stack, le variabili di un frame |
debug_step |
step_over, step_into, step_out, run, stop: attende la fermata successiva |
debug_run_to |
avanza fino a una riga |
debug_eval |
valuta un'espressione PHP dove si è fermato |
debug_variables |
le variabili di un frame, o i figli di una ($this->player, $list[3]) |
debug_set_value |
dà un nuovo valore a una variabile (un'espressione PHP) |
I percorsi sono relativi al progetto. Claude avvia il programma da solo, in background, con JUMPHP_XDEBUG=9003, poi chiama debug_wait.
2. Il server di PHP Debugger: dbgp mcp
PHP Debugger fornisce il proprio server MCP in un piccolo programma, dbgp (licenza MIT; Linux e macOS, amd64 e arm64; Windows amd64).
# installazione (macOS / Linux)
curl -fsSL https://github.com/php-debugger/dbgp-client/releases/latest/download/install.sh | sh
dbgp -version
# per questo progetto / per tutti i tuoi progetti
claude mcp add dbgp -- dbgp mcp
claude mcp add --scope user dbgp -- dbgp mcp
In Claude Code, /mcp mostra che è connesso. I suoi strumenti, con i nomi della documentazione di PHP Debugger:
- connessione:
status,listen,unlisten,sessions,wait_for_session,detach; - punti di interruzione:
add_breakpoint,remove_breakpoint,breakpoints; - esecuzione:
continue,wait_for_stop,stop; - guardare:
stack,variables,variable,variable_value,source,output,warnings; - agire:
eval,set_variable; - Docker / remoto:
add_path_mapping,path_mappings.
Opzioni utili (dbgp mcp -h per tutte): -php-port PORTA (la porta a cui si collega PHP, 9003 per default), -mcp-port PORTA, -idekey CHIAVE, -map LOCALE=REMOTO (una corrispondenza di percorsi, ripetibile) e -no-eval, che vieta eval, set_variable e i punti condizionali: l'IA può solo guardare. Non nasconde i valori: password e chiavi restano visibili per lei.
Con bin/jumphp, JUMPHP_DEBUGGER=php-debugger bin/jumphp debug avvia dbgp mcp per te (serve dbgp installato sul tuo computer). Poi avvia il programma con lo stesso motore:
JUMPHP_DEBUGGER=php-debugger JUMPHP_XDEBUG=9003 bin/jumphp test pong
Una sessione di esempio
Tu, a Claude Code:
Il punteggio del gioco
pongsale di 2 invece di 1 quando la palla supera la racchetta sinistra. Usa il debugger, non var_dump. Metti un punto di interruzione dove il punteggio aumenta (cerca inPlayScene), eseguibin/jumphp test pongconJUMPHP_XDEBUG=9003, fermati lì, leggi le variabili e dimmi perché. Correggi solo dopo avermi mostrato la causa.
Cosa fa allora l'IA, con gli strumenti sopra:
- trova la riga che aggiunge un punto e vi mette un punto di interruzione, con una condizione se la riga passa a ogni fotogramma (
$this->ballX < 0); - avvia il test in background e attende la fermata (
debug_wait/wait_for_stop); - legge
$this->score,$this->scorede lo stack per vedere chi ha chiamato quella riga; - esce una volta (
debug_stepstep_out) per vedere il secondo chiamante: il punto è contato due volte; - verifica la sua idea senza modificare nulla: dà un valore a
$this->scored(debug_set_value/set_variable) e prosegue per vedere il punteggio restare giusto; - solo allora modifica il codice e rilancia il test, senza punto di interruzione.
Consigli
- Dillo chiaramente: «usa il debugger». Altrimenti un agente ripiega spesso su
var_dump(). - Dalle il comando che mostra il bug, ciò che ti aspetti e dove sospetti il problema.
- Piccoli passi: qualche
step_over, poi si guarda. Un punto condizionale ($enemy->hp <= 0) vale più di 600 fotogrammi passo passo. - Lasciala leggere le variabili e valutare espressioni: niente
var_dump(), nienteecho, nulla da ripulire dopo. - Preferisci le esecuzioni senza finestra (
test,shot,php). - Segreti: l'IA vede tutte le variabili che legge (password, token, chiavi API). Fai il debug con dati di prova e usa
-no-evalcondbgpse non vuoi che esegua codice nel tuo programma. - Non lasciare collegato il server MCP di un debugger in un progetto in cui non fai debug: toglilo con
claude mcp remove.
Risoluzione dei problemi
Niente si ferma / «did not connect».
Un debugger è in ascolto sulla porta (la finestra Debug dell'IDE o un server MCP)? Il programma deve essere avviato con JUMPHP_XDEBUG=<porta> e lo stesso motore di chi ascolta.
Porta già in uso.
Due ascoltatori su 9003: l'IDE e bin/jumphp debug (o dbgp mcp), o due IDE. Fermane uno, o usa un'altra porta: JUMPHP_DEBUG_PORT=9010 bin/jumphp debug con JUMPHP_XDEBUG=9010, oppure dbgp -php-port 9010 mcp.
Il punto di interruzione non viene mai raggiunto.
È su una riga senza codice (commento, riga vuota, parentesi di chiusura) o in un file che il programma non carica mai. Usa debug_state / guarda lo stack per vedere dov'è. Con -map o un IDE: i percorsi devono corrispondere (sotto).
Percorsi in Docker.
bin/jumphp monta il tuo progetto in /workspace nel contenitore: il debugger dice file:///workspace/.... L'IDE e bin/jumphp debug lo associano da soli ai file del progetto, e i percorsi che dai sono relativi al progetto. Con dbgp mcp da solo, associa le cartelle: dbgp mcp -map /home/tu/progetto=/workspace.
PHP 8.6 (runtime async).
PHP Debugger non gira lì: si usa Xdebug. Per usare PHP Debugger, fai il debug sul runtime predefinito (PHP 8.5) o togli runtime: async per la sessione.
Giochi nel browser.
Il debugger lavora sul runtime desktop. Nel browser, riproduci il bug con bin/jumphp test o shot sul desktop.
Vedi anche Programmare, avviare e testare, Claude nell'IDE e IDE Remote.