In questo articolo inizieremo a trattare XDebug più in dettaglio iniziando da una delle funzionalità principali della libreria: il debugging. Nel mondo della programmazione vi sono diversi modi per effettuare il debug del codice, e quello che offre XDebug fa sicuramente parte dei più avanzati permettendo parecchie operazioni importanti .
Normalmente un debugger è una versione speciale dell'interprete che ha come compito quello di interpretare istruzioni aggiuntive (presenti nel codice oppure impartite da linea di comando a runtime) che permettono l'analisi dello stack in ogni momento, l'esecuzione passo passo, la valutazione di espressioni in un determinato momento durante il ciclo di vita di un'applicazione. I debugger solitamente funzionano come dei veri e propri server che scambiano messaggi con i client attraverso dei protocolli più o meno standard; questo tipo di struttura permette flessibilità nello sviluppo del client che, presupponendo la chiarezza e la portabilità del protocollo, può essere integrato anche in tool esterni già esistenti.
XDebug funge anch'esso da server di debugging, estendendo l'interprete stesso di PHP; utilizza un protocollo molto semplice per scambiare i dati con il client ed è in grado di eseguire moltissimi comandi interessanti. Normalmente il debugger viene utilizzato da linea di comando ma, per chi fosse abituato ad editor e debugger grafici, è a disposizione un'estensione di Eclipse che permette il debugging grafico: PDT.
In questo articolo parleremo per l'appunto di PDT e nello specifico del modulo che permette il debugging degli script PHP. Personalmente non amo Eclipse, ma lo ritengo comunque uno strumento valido nel caso non si sia particolarmente portati all'uso della linea di comando e non si vogliano spendere soldi per lo Zend Studio.
Primi passi con PDT
In primis è necessario procurarsi una copia di Eclipse ed installarvi l'estensione PDT. PDT (acronimo di PHP Development Tools) è una buona estensione per Eclipse, multi piattaforma, con supporto nativo per XDebug; l'installazione è molto semplice, e prevede il download del pacchetto corretto dal sito http://eclipse.org/pdt e la successiva installazione come normale modulo per Eclipse.
Generalmente l'utilizzo di XDebug per il debugging prevede due metodologie di lavoro, controllate attraverso la proprietà:
xdebug.remote_mode
Questa proprietà può assumere due differenti valori: req
e jit
. Nel primo caso il debugger cercherà di connettersi sempre ad un client quando uno script verrà iniziato; nel secondo caso invece il debugger si connetterà al client solamente nel caso in cui incontrerà un breakpoint all'interno del flusso di codice. Una sessione di debugging, per poter essere iniziata, necessita l'invio della variabile XDEBUG_SESSION_START
al server utilizzando un cookie, GET
oppure POST
. Questa variabile rappresenta un identificativo univoco per la sessione in esecuzione.
Anche se non eccessivamente complesse, queste operazioni vengono automatizzate da PDT che, previa corretta configurazione del file php.ini e del client, invierà automaticamente la sessione univoca e controllerà l'esecuzione del server di debug. La configurazione del file php.ini è la più semplice, e prevede l'attivazione del debugger remoto e l'impostazione dell'host e della porta da utilizzare per il server:
xdebug.remote_enable = On xdebug.remote_host = "localhost" xdebug.remote_port = 9000
XDebug è un debugger remoto, quindi ricordatevi che è possibile connettersi ad un debugger che gira su un server differente da quello locale. Per semplicità stiamo analizzando uno scenario in cui client e server risiedono sulla stessa macchina.
Per quanto riguarda la configurazione di PDT, anche in questo caso le operazioni sono molto semplici; in primo luogo va ricordato che PDT è in grado di effettuare il debugging su script eseguiti sia nel web browser interno che su browser esterni (questo grazie alla struttura client server di XDebug). Volendo quindi possiamo impostare la proprietà di Eclipse correlata e procedere.
PDT supporta anche Zend Debug, ma attualmente siamo interessati ad XDebug e quindi possiamo andare nelle proprietà di Eclipse, all'interno di PHP > Debug, e cambiare la proprietà PHP Debugger in XDebug.
Ora creiamo da zero un progetto PHP di esempio, creando un file PHP chiamato test.php contenente del codice funzionante a vostra scelta. Ora il nostro obiettivo è quello di creare una nuova configurazione di debug per eseguire gli script PHP, da utilizzare ogni qualvolta vorremo debuggare del codice. Nella barra dei tool selezioniamo Run e quindi Open Debug Dialog; successivamente facciamo doppio click sulla label PHP Web Page e creiamo una nuova configurazione. La nuova configurazione contiene tre tab contenenti parecchie informazioni; per "debuggare" correttamente lo script con XDebug dobbiamo assicurarci che alcuni punti siano correttamente impostati:
- Impostare Xdebug come valore per Server Debugger. Dovrebbe essere già impostato come valore di default
- Impostare all'interno del campo File / Project il path (relativo al progetto) del file su cui si desidera eseguire il debug. Possiamo inserirlo manualmente oppure recuperarlo direttamente dal filesystem usando il tasto Browse
- Controllare che il campo URL sia impostato correttamente. Questo campo contiene l'indirizzo del file che stiamo testando; questo indirizzo viene utilizzato per mappare correttamente il codice sorgente al codice eseguito e, nel caso in cui sia selezionata l'opzione Auto Generate, è impostato automaticamente. Nel caso fosse errato, possiamo rimuovere l'opzione Auto Generate ed impostarlo manualmente. È necessario modificare l'URL anche nel caso in cui fosse necessario inviare dei parametri GET espliciti alla pagina da testare
Dopo esserci assicurati che tutto è stato impostato correttamente, possiamo salvare i cambiamenti cliccando Apply e partire col il debugging del nostro script.
Utilizzare PDT per debuggare uno script PHP
Ora che abbiamo configurato a dovere PDT, possiamo provare a "debuggare" uno script PHP. Apriamo lo script di esempio che abbiamo creato precedentemente ed avviamolo in versione di debug selezionano Run / Debug. Lo script viene avviato ed automaticamente, dato che non sono stati impostati ancora breakpoint, l'esecuzione viene interrotta alla prima riga di codice; potete disabilitare questo comportamento rimuovendo l'opzione Break at First Line del pannello Breakpoint che potete trovare nella finestra di configurazione. Nel caso in cui fosse la prima volta che avviate uno script in versione di debug, vi verrà chiesto se desiderate aprire automaticamente la prospettiva di debugging nel caso in cui l'IDE lo richieda. Selezionate in modo affermativo e vi troverete di fronte la prospettiva di debug, che include il codice sorgente dello script in esecuzione. Lo stack delle chiamate effettuate per arrivare allo script ed alcuni dati aggiuntivi molto interessanti come le variabili accessibili, la lista dei breakpoints.
Da questa schermata potete impostare nuovi breakpoint ovunque riteniate opportuno interrompere nuovamente l'esecuzione del codice, cliccando sul margine sinistro nella vista che mostra il codice sorgente. Utilizzando i pulsanti del pannello Debug potete inviare comandi al debugger remoto, istruendogli di riprendere l'esecuzione fino alla prossima interruzione, terminando l'esecuzione oppure navigando l'esecuzione. Le opzioni di navigazione dell'esecuzione riga per riga sono molto utili:
- Potete eseguire la riga attuale ed interrompere l'esecuzione nuovamente alla riga successiva
- Potete eseguire tutto il codice finché non uscite dallo scope corrente
- Potete eseguire tutto il codice finché la funzione attuale non restituisce un valore
Ogni volta che navigate il codice, i pannelli contenenti le informazioni di esecuzione vengono aggiornati di conseguenza mostrando le variabili accessibili ed i rispettivi valori. Questi valori possono essere modificati a runtime, editando il valore corrispondente e premendo INVIO per salvare la modifica.
L'utilizzo di breakpoint nel codice è di gran lunga l'opzione più utilizzata rispetto che l'esecuzione riga per riga; ci sono situazioni in cui i breakpoint però rallentano parecchio il debugging di uno script: pensate ad esempio all'interno di un ciclo di centinaia di valori nel quale volete procedere con l'analisi dello stato solamente per gli ultimi valori analizzati. In aiuto XDebug ci fornisce due opzioni interessanti:
- la possibilità di impostare i breakpoint a runtime, mentre il codice è in esecuzione ed è stato interrotto da un altro breakpoint o da un'altra condizione
- la possibilità di impostare delle espressioni che fungano da condizione per l'interruzione o meno del codice in quel determinato punto
Impostare una condizione è molto semplice: basta premere con il pulsante destro del mouse sul breakpoint, selezionare Set Condition ed inserire un'espressione valida PHP che faccia uso delle variabili locali.