Nello scorso articolo abbiamo introdotto XDebug, la libreria nativa per PHP che permette il debugging avanzato degli script PHP. Ci siamo soffermati sul processo di installazione della libreria, discutendo anche brevemente di quali sono le funzionalità normalmente utilizzate in fase di debugging e quali di queste sono disponibili in XDebug.
Da questo articolo in avanti ci soffermeremo su qualcosa di più pratico, analizzando la maggior parte delle funzioni a disposizione e descrivendo di volta in volta quali sono le opzioni di configurazione relative alla funzionalità che stiamo analizzando.
Prima di inziare
Brevemente, prima di iniziare, ricordiamoci che è possibile abilitare o disabilitare alcune funzionalità automatiche di XDebug dal file php.ini come una qualunque estensione. Ricordo a chiunque fosse sfuggito che XDebug non è compatibile con le altre estensioni native che funzionano a livello di kernel come ad esempio APC - Advanced PHP Cache, di cui abbiamo parlato qualche mese fa - e che quindi non basta disabilitare queste funzionalità automatiche dal file di configurazione se si desidera utilizzare qualche libreria incompatibile, ma bisogna necessariamente rimuovere XDebug dalle estensioni incluse (commentando la riga relativa nel file php.ini).
Comunque risulta spesso utile abilitare o disabilitare queste funzionalità di XDebug, e lo si può fare utilizzando la seguente opzione di configurazione:
Boolean xdebug.default_enable
Assegnando il valore On alla proprietà, si abilitano tutte quelle funzionalità di default che vengono aggiunte da XDebug, come ad esempio la tracing automatico dello stack (visualizzazione dello stacktrace) in caso si generino errori non gestiti.
Assegnando Off alla proprietà queste funzionalità vengono disabilitate.
Un'altra opzione di configurazione interessante è quella che permette di controllare il numero di chiamate ricorsive ad una funzione, così da bloccare loop ricorsivi infiniti:
Integer xdebug.max_nesting_level
Impostando questo valore ad un intero maggiore di 0, si limita il numero di chiamate annidate possibili. Sarebbe opportuno mantenere un valore abbastanza alto affinché sia permesso a script abbastanza complessi di operare in modo corretto anche su grosse quantità di dati, ed in generale assicurarsi che il numero sia abbastanza alto per permettere ai nostri script di essere eseguiti correttamente.
Analisi degli errori
Normalmente quando viene generato un errore in PHP, l'interprete genera un messaggio di errore (la cui cripticità varia in base alla situazione ...) che viene stampato a video insieme a pochissime altre informazioni inerenti. Capita spesso quindi che, quando viene trovato un errore di runtime ad una determinata riga, si aggiungano var_dump ed echo vari per conoscere la situazione in cui ci si trova quando l'errore viene generato (oppure si utilizzano più o meno avanzati sistemi di logging che possono piacere a qualcuno).
Come accennato precedentemente XDebug estende la gestione degli errori di PHP, includendo moltissime informazioni aggiuntive che ci facilitano di gran lunga le operazioni quando ci si trova a dover lavorare con progetti molto grossi sui quali molte persone mettono le mani. Oltre al messaggi di errore, XDebug visualizza lo stack trace che ha portato alla chiamata della funzione in cui è contenuto l'errore, visualizzando anche (se esplicitamente richiesto assegnando le appropriate opzioni di configurazione che vedremo a breve) il valore delle variabili locali ed eventualmente di quelle globali.
Questa opzione funziona solamente se la proprietà display_errors è impostata ad On.
Di default possiamo visualizzare lo stacktrace, che mostra oltre che la catena di chiamate a funzione che hanno portato all'esecuzione della riga di codice che ha generato l'errore, anche i millisecondi ai quali è partita la chiamata, la riga ed il file da cui è partita la chiamata ed il quantitativo di mermoria quando la funzione è stata chiamata. In questo modo abbiamo un'idea generale dello stato dell'esecuzione al momento dell'errore.
Se si desidera avere un idea più precisa della situazione in cui si trovava il programma quando è stato generato l'errore, è possibile richiedere ad XDebug di visualizzare anche le variabili locali utilizzando il seguente comando di configurazione:
Boolean xdebug.show_local_vars
Impostandolo ad un valore diverso da zero (oppure On), XDebug visualizzerà la lista delle variabili locali presenti nello stack quando un errore è stato generato. Di default questa opzione è disattivata poiché in alcune situazioni è possibile che il numero di variabili locali visualizzate sia parecchio ampio.
In caso lo si desideri è possibile anche visualizzare le variabili superglobali insieme allo stacktrace, abilitando esplicitamente la visualizzazione con la seguente opzione di configurazione:
Boolean xdebug.dump_globals
Impostandola ad On visualizzeremo anche il valore delle variabili superglobali.
Controllare e filtrare i valori visualizzati
Spesso gli script sono complessi, ed i dati visualizzabili in caso di errore e con abilitate tutte le opzioni possibili sono veramente tanti. Fortunatamente XDebug ci permette di filtrare i valori visualizzati, limitando il numero di figli degli array, la lunghezza delle stringhe e filtrando gli array superglobali.
Queste opzioni vengono utilizzate ogni volta che XDebug ha necessità di stampare a video il contenuto di alcune variabili. Per esempio la funzione var_dump di PHP viene estesa da XDebug in modo da includere output filtrato e stampato in modo molto più leggibile rispetto all'output normalmente generato da PHP.
Le opzioni da prendere in considerazione sono svariate: possiamo limitare il numero di caratteri visualizzati per una stringa (il valore di default impostato da XDebug è 512) modificando il seguente parametro:
Integer xdebug.var_display_max_data
Assegnando un valore intero maggiore di zero possiamo limitare il numero di caratteri di una stringa. Per fare una prova del suo funzionamento, utilizzate la funzione var_dump per stampare una stringa. Successivamente modificate il valore di configurazione assegnando un valore inferiore alla lunghezza della stringa, riavviate Apache ed eseguite nuovamente il vostro script di test: il valore delle stringa verrà opportunamente troncato in base al valore impostato.
XDebug permette anche di limitare il numero di figli di un array visualizzati. Il valore impostato di default è 128, ma possiamo modificarlo cambiando il valore della seguente opzione di configurazione:
Integer xdebug.var_display_max_children
Assegnando un valore intero maggiore di zero possiamo controllare quanti figli XDebug visualizzerà per gli array che verranno stampati. Possiamo effettuare la stessa prova suggerita precedentemente per controllare il corretto funzionamento, oppure possiamo generare volutamente un errore PHP all'interno di uno script complesso per avere una visione più completa delle opzioni applicate.
Un'altra operazione molto comune quando si utilizza XDebug e si desidera anche visualizzare il contenuto delle variabili superglobali, è quella di filtrare i valori visualizzati limitando sia le variabili da visualizzare che le chiavi di cui stampare i valori. Per controllare queste opzioni dobbiamo intervenire sulle opzioni xdebug.dump.*; per ogni variabile superglobale è presente una opzione di configurazione che inizia con questo prefisso: per esempio se vogliamo intervenire sulla variabile $_SERVER possiamo modificare il valore dell'opzione di configurazone xdebug.dump.SERVER.
Il valore di questa opzione è una stringa, che rappresenta una lista separata da virgole di tutte le chiavi che vogliamo visualizzare per una variabile superglobale. Possiamo usare l'asterisco (*) nel caso in cui vogliamo includere tutte le chiavi, senza la necessità di doverle specificare una ad una.
Ad esempio se vogliamo visualizzare solamente l'url da cui proviene la richiesta ad una pagina, possiamo impostare le opzioni come segue:
xdebug.dump.SERVER = 'HTTP_REFERER'
Se invece siamo interessati a visualizzare tutti i parametri invia via post, e magari avere qualche informazioni aggiuntiva sull'server, possiamo scrivere:
xdebug.dump.SERVER = 'HTTP_REFERER,SERVER_NAME, HOST_NAME'
xdebug.dump.GET = '*'
Unendo queste opzioni di configurazione alla fatto che XDebug estende in modo interessante gli output degli errori e della funzione var_dump, possiamo ottenere degli output molto dettagliati che ci assicurino informazioni complete ogni volta fosse necessario.
Conclusione
In questo articolo abbiamo introdotto in modo generico alcune opzioni di configurazioni relative all'output generato da XDebug. Nel prossimo articolo della serie inizieremo a parlare di funzionalità interessanti utilizzabili da codice per ottenere informazioni a runtime interessanti che possono servire sia per il debugging, che per il logging che, in alcuni casi, per migliorare la metaprogrammazione in PHP.