lunedì 9 luglio 2012

PHP & NetBeans: Debug di codice sorgente PHP con NetBeans

Mi sono preso la briga di tradurre questo post originariamente ospitato nu NetBeans.org ed ora da Apache perchè spiega bene come fare il debug di progetti PHP con NetBeans. In fondo il link all'articolo originale in lingua inglese.
Contenuti

  • Pronti a Partire
  • Come lavora il debugger PHP in NetBeans con XDebug
  • Opzioni di Debug
  • Lavorare con la ToolBar e L'Editor
  • Finestre del Debugger
  • Sessione di Debug
  • Esempio di Sessione di Debug
  • Utilizzare Watches Aggiuntivi
  • Casi in cui PHP e HTML sono Mescolati
  • Mappatura, Debugger Proxy e Avvio della Sessione di Debug su un URL Personalizzato
Per seguire questo tutorial, hai bisogno di quanto segue.
Software o risorseVersione Richiesta
NetBeans IDEScarica il pacchetto per PHP
Un motore PHPVersione 5
Un Web ServerApache HTTP Server 2.2 è raccomandato.
Un debugger PHPXDebug 2.0 o successivo

Pronti a Partire

Per effettuare il debug di applicazioni PHP con NetBeans, è necessario avere il motore PHP, il web server locale Apache, e il debugger XDebug installati e configurati per l'ambiente di sviluppo PHP. Se hai difficoltà nel porre al lavoro XDebug, vedi il NetBeans wiki on XDebug o chiedi alla comunità a user@php.netbeans.org

Come lavora il debugger PHP in NetBeans con XDebug

Quando esegui XDebug dall'IDE di NetBeans, l'esecuzione del programma PHP si ferma ad ogni linea in cui hai impostato un breakpoint. Quando l'esecuzione del programma è in pausa, XDebug recupera le informazioni sullo stato corrente del programma, come il valore delle variabili. Praticamente, si ha il seguente workflow:
  1. Impostare un breakpoint in cui l'esecuzione del codice sorgende dovrebbe andare in pausa.
  2. Avviare una sessione di debug.
  3. Quando si raggiunge una linea con un breakpoint, eseguire lo script una linea dopo l'altra pigiando F7 e F8. Monitorare lo stato dell'applicazione nella finestra del debugger.
  4. Chiudere la sessione di debug.
Per un dettagliato workflow dell'uso di XDebug con l'IDE di NetBeans, vedere "Sessione di Debug".
NetBeans fornisce una toolbar di debug che aiuta nell'attraversare i tuoi file. Vedere "Lavorare con la Tollbar e l'Editor".

Opzioni di Debug

Le Options dell'IDE di NetBeans comprendono una scheda per cambiare certe impostazioni di default per il debug di PHP. Per accedere a queste opzioni, andare in Tools > Options (NetBeans > Preferences su Mac), seleziona le opzioni PHP, e seleziona la scheda Debugging.
Nota: La scheda Debugging è stata introdotta da NetBeans 7.1. Precedenti versioni di NetBeans hanno le opzioni di debug nella scheda General. Non tutte le opzioni della versione 7.1 sono disponibili nelle precedenti versioni.

In questo pannello è possibile cambiare le seguenti opzioni:
  • Debugger port E' la porta utilizzata da XDebug, come impostata nel php.ini. La porta di default è 9000. Il numero di porta in questa finestra di dialogo deve essere la stessa impostata nel php.ini. Non puoi influenzare la porta utilizzata da XDebug da questa finestra di dialogo. Puoi solo informare NetBeans su quale porta è utilizzata da XDebug.
  • Session ID Nome arbitrario della sessione di debug. Per default è netbeans-xdebug. E' importante annotare questo valore nel caso in cui devi impostare la proprietà xdebug.idkey in php.ini, come negli scenari d i debug  remoto.
  • Stop at First Line Spunta questa opzione fermare l'esecuzione alla prima linea di codice piuttosto che al primo breakpoint. Questa opzione lascia in primo piano l'IDE invece di passare alla finestra del browser quando avvii una sessione di debug.
  • Watches and Balloon Evaluation Watches and Balloon Evaluation è disabilitata per default. Watches and Balloon Evaluation destabiliza XDebug.
  • Maximum Depth of Structures. Imposta la visibilità di strutture annidate (come array annidati, oggetti in oggetti, ecc.)
  • Maximum Number of Children. Imposta la visibilità di voci di array durante la Watch Evaluation. Se imposti Maximum Number of Children a 1 vedrai solo la prima voce di un array anche se l'array ha più di un elemento.
  • Show Requested URLs. Apre una nuova Output window durante il debug. Questa Output windows è chiamata PHP Requested Urls e mostra le Urls correntemente elaborate. Le Urls sono cliccabili. Clicca su una URL nella Output window per aprirla nella finestra del browser.
  • PHP Debugger Console. Apre una nuova Output window che mostra l'output dello script sottoposto a debug.
    Nota: Imposta output_buffering = Off in php.ini. Altrimenti ci sarà un ritardo nella visualizzazione dell'output dello script nella Output window.
Ai fini di questo tutorial, non hai bisogno di cambiare alcuna di queste impostazioni, a meno eventualmente dell'abilitazione dei Wathces (vista del contenuto delle variabili).

Lavorare con la Toolbar e L'Editor

L'editor ti permette di visualizzare il contenuto dei file. Quando esegui il debug, l'editor in combinazione con la toolbar del debugger, consente di attraversare il codice in esecuzione al fine di vedere come i contenuti del tuo file agiscono su quanto accede nel browser.
  • Utilizzare la Toolbar del Debugger
  • Impostare i Breakpoint
  • Esaminare i Tooltip

Utilizzare la Toolbar del Debugger

Quando avvii una sessione di debug, la toolbar del debugger appare sopra l'editor.

La toolbar permette di compiere le seguenti azioni:
Finish Session ()Concludere la sessione di debug
Pause ()Sospendere la sessione di debug
Resume ()Ripristinare la sessione di debug
Step Over ()Procede con l'esecuzione fino all'istruzione successiva
Step Into ( )Andare all'interno di una chiamata di funzione
Step Out ()Procedere con l'esecuzione fino all'uscita
dalla chiamata di funzione corrente
Run to Cursor ()Procedere con l'esecuzione fino alla
posizione corrente del cursore


Impostare i Breakpoint

Imposta i breakpoint per dire al debugger dove fermarsi durante l'esecuzione.
Importante: Devi impostare i breakpoint nel tuo codice PHP per utilizzare XDebug.
Per impostare un breackpoint, clicca sul margine sinistro dell'editor sul numero di linea in cui vuoi che sia impostato il breakpoint.


Puoi rimuovere il breakpoint cliccando sul simbolo del breakpoint ().
E' anche possibile disabilitare temporaneamente i breakpoint, Per farlo, fai clic con il tasto destro sul simbolo di un breakpoint e deseleziona Breakpoint > ✔Enabled. Ciò alterna il breakpoint nello stato disabilitato, evidenziato da un simbolo grigio () visualizzato sul margine sinistro.
Se il debugger incontra un breakpoint durante l'esecuzione, si ferma sul breakpoint, permettendoti di esaminare le variabili nelle finestre di debug, e camminare attraverso il codice seguente il breakpoint.


Esaminare i Tooltip

Quando il debugger è sospeso durante una sessione di debug, puoi portare il mouse sopra un identificatore PHP nell'editor per visualizzare un tooltip. Se all'interno dello stack delle chiamate selezionato l'identificatore è valido, il suo valore è visualizzato. Puoi anche selezionare espressioni PHP. Il valore dell'espressione è mostrato in un tooltip.

Finestre del Debugger

Quando avvii una sessione di debug, sono aperte un insieme di finestre del Debbuger al di sotto della finestra principale dell'editor. Le finestre del debugger permettono di tenere traccia dei valori di variabili ed espressioni man mano che si avanza nel codice, esaminare lo stack delle chiamate dell'esecuzione di un thread, verificare il sorgente della URL, e passare da una sessione all'altra se stai eseguendo sessioni di debug concorrenti.
  • La finestra Sessions
  • La finestra Variabiles
  • La finsetra Watches
  • La finestra Call Stack
  • La finestra Threads
  • La finestra Sources
  • La finestra Breakpoints
Tutte le finestre del debugger sono accessibili dal menu dell'IDE Window > Debugging. Una volta che una sessione di debug è attiva, puoi iniziare a far uso delle finestre del debugger.



La finestra Sessions

La finestra Sessions motra le sessioni di debug attive. Quando avvii una sessione di debug PHP, puoi vedere una voce per il debugger PHP nella finestra Sessions.


L'IDE NetBeans permette anche di eseguire sessioni multiple del debugger simultaneamente. Per esempio, puoi fare il debug di un progetto Java e un progetto PHP allo sesso tempo. In questo caso, puoi identificare le due sessioni nella finestra Sessions.


La sessione corrente (per esempio, la sessione che puoi controllare utilizzando la toolbar del debugger) è indicata dall'icona più evidente (). Per passare ad un'altra sessione, puoi fare doppio clic sulla sessione che vuoi rendere corrente, o tasto destro su una sessione non corrente e scegliere Make Current.
Nota: Non è raccomandabile cambiare sessione se la sessione su cui stai lavorando è sospesa.
Puoi anche utilizzare la precedente finestra di pop-up per terminare una sessione (tasto destro e scegli Finish), o alternare tra il debug del thread corrente o di tutti i thread all'interno della sessione (tasto destro e scegli Scope > Debug All Threads o Debug Current Thread).

La finestra Variables

Quando il debugger è sospeso, la finestra Variables della finestra corrente per la chiamata selezionata nello stack. Un nodo è visualizzato per ogni variabile nella finestra corrente. Le Superglobals sono raggruppate sotto un nodo separato.

Man mano che avanzi nel codice, il valore di qualche variabile locale potrebbe cambiare. Tali variabili sono mostrate in grassetto nella finestra delle variabili Local. Puoi anche cliccare direttamente sulla colonna Value e cambiare manualmente il valore delle variabili.

La finestra Watches

Impostare dei watches destabilizza XDebug e non è raccomandabile. I Watches sono disabilitati di default. Comunque se vuoi impostare i watches, vedi "Utilizzare Watches Aggiuntivi". 

La finestra Call Stack 

La finsetra Call Stack elenca la sequenza delle chiamate fatte durante l'esecuzione. Quando il debugger è sospeso, la finestra Call Stack mostra la sequenza delle funzioni chiamate (per esempio lo stack delle chiamate). Alla prima sospensione, la chiamata in cima allo stack è selezionata automaticamente. Con un doppio clic su una chiamata di funzione conduce a quella linea nell'editor. Se la chiamata è fatta a una classe PHP, anche la finestra Navigator va a quella linea facendo doppio clic sulla chiamata.


Puoi fare doppio clic su una chiamata nello stack per selezionarla, quindi esplorare qualunque valore di variabile o espressione per quella chiamata nelle finestre Variables e Watches.

La finestra Threads

La finestra Threads indica quale script PHP è attualmente attivo e se è sospeso ad un breakpoint o è in esecuzione. Se lo script è in esecuzione, hai bisogno di andare alla finestra del browser per interagire con lo script.


La finestra Sources

La finestra Sources visualizza tutti i file e gli script caricati per la sessione di debug. La finestra Sources al momento non è funzionante per progetti PHP.

La finestra Breakpoints

Puoi utilizzare la finestra Breakpoints per vedere tutti i breakpoint impostati nell'IDE.


Dalla finestra Breakpoint puoi abilitare o disabilitare i breakpoint nel menu contestuale. Puoi anche creare gruppi di breakpoint.

Sessione di Debug

La seguente procedura rappresenta il workflow di una tipica sessione di debugging.
Per eseguire una sessione di debug:
  1. Avvia l'IDE e apri il file che contiene il codice sorgente su cui effettuare il debug.
  2. Imposta un breakpoint su ogni linea in cui vuoi che il debugger vada in pausa. Per impostare un breakpoint, poni il cursore all'inizio della linea e premi CTRL-F8/⌘-F8 o scegli Debug > Toggle Line Breakpoint.
  3. Nella finestra Projects, vai al nodo del progetto corrente, clicca con il tasto destro del mouse, e scegli Debug dal menu contestuale. L'IDE apre le finestre del Debugger ed esegue il progetto nel debugger finché non raggiunge un breakpoint
    Nota: Se il progetto corrente è impostato come Main, puoi scegliere Debug Main Project, o premere CTRL-F5, o cliccare su.
  4. Passare alla finestra Local Variables. La finestra mostra tutte le variabili che sono state inizializzate con la funzione corrente, il loro tipo e valore.
  5. Per vedere il valore di una variabile al di fuori della funzione, portare il cursore su un occorrenza della variabile. Il tooltip mostra il valore della variabile.
  6. Per eseguire il programma linea per linea, comprese le linee all'interno delle chiamate di funzioni, premi F7 o scegli Debug > Step Into e osserva i cambiamenti ai valori delle variabili nella finestra Local Variables.
  7. Per controllare la logica del programma osservando il cambiamento delle espressioni, definisci nuovi Watches:
    1. Per aprire la finestra Watches, scegli Window > Debugging > Watches o premi CRTL-Shift-2. La finestra Watches si apre.
    2. Ovunque all'interno della finestra Watches, fai clic con il tasto destro del mouse e scegli New Watch dal menu contestuale. La finesta New Watch si apre.
    3. Inserisci l'espressione da osservare e clicca su OK.
    E' possibile fare controlli aggiuntivi durante il debug.
    Importante: Devi abilitare i Watches nella Scheda delle Opzioni di Debug di PHP per poterli impostare.
  8. Per annullare l'esecuzione linea per linea all'interno di una funzione e andare alla linea successiva la chiamata di funzione, premi CTRL-F7/⌘-F7 o scegli Debug > Step Out.
  9. Per saltare l'esecuzione linea per linea del codice di una funzione, ottenere il valore tornato dalla funzione, e andare alla linea successiva la chiamata di funzione, premi F8 o scegli Debug > Step Over.
  10. Per mettere in pausa la sessione di debug, scegli Debug > Pause.
  11. Per riavviare la sessione di debug, scegli Debug > Continue o premi.
  12. Per cancellare la sessione di debug, premi.
  13. Quando il programma raggiunge la fine, le finestre del debugger sono chiuse.

Esempio di Sessione di Debug

L'esempio in questa sezione illustra le funzioni di base del debugger, comprese le funzioni di step into e over. Mostra anche il tipico output della finestra del debugger.
  1. Creare un nuovo progetto PHP con i seguenti parametri:
    • Project type - PHP application
    • Sources location - la cartella htdocs  di default
    • Run configuration - Local Web Site
    Trovi maggiori informazioni sulla configurazione di un progetto PHP nel documento Setting Up a PHP Project.
  2. Per permettere l'uso degli hotkey durante la sessione, posizionare il cursore sul nodo del progetto e scegliere  Set as Main Project dalla menu contestuale.
  3. Nel file index.php, inserire il seguente codice:
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      <html>
       <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
         <title>NetBeans PHP debugging sample</title>
      </head>
    <body>
     <?php
       $m=5;
       $n=10;
         $sum_of_factorials = calculate_sum_of_factorials ($m, $n);
         echo "The sum of factorials of the entered integers is " . $sum_of_factorials;
       
         function calculate_sum_of_factorials ($argument1, $argument2) {
         $factorial1 = calculate_factorial ($argument1);
         $factorial2 = calculate_factorial ($argument2);
         $result = calculate_sum ($factorial1, $factorial2);
         return $result;
        }
     
       function calculate_factorial ($argument) {
          $factorial_result = 1;
         for ($i=1; $i<=$argument; $i++) {
          $factorial_result = $factorial_result*$i;
         }
         return $factorial_result;
        }
       
         function calculate_sum ($argument1, $argument2) {
        return $argument1 + $argument2;
          } 
    ?>
      </body>
    </html>
      
    Il codice contiene tre funzioni:
    • La funzione calculate_factorial () 
    • La funzione calcualte_sum () 
    • La funzione calculate_sum_of_factorials () che chiama la funzione calculate_factorial () due volte, poi chiama la funzione calcualte_sum () una volta, e ritorna la somma dei fattoriali calcolati.
  4. Imposta un breakpoint (Ctrl-F8/⌘-F8) all'inizio del blocco PHP:
    <?php
  5. Per avviare il debug, clicca. Il debugger si ferma al breakpoint.
  6. Premi F7 tre volte. Il debugger si ferma alla line in cui è chiamata la funzione calculate_sum_of_factorials (). La finestra Local Variables mostra le variabili $m e $n con i loro valori:

  7. Per avanzare all'interno della funzione calculate_sum_of_factorials(), premi F7. Il debugger avvia l'esecuzione del codice all'interno della funzione calculate_sum_of_factorials () e si ferma alla chiamata della funzione calculate_factorial().


    La finestra Local Variables ora mostra le variabili locali $argument1 e $argument2 che sono dichiarate all'interno della funzione calculate_sum_of_factorials ().

  8. Premi F7. Il debugger avvia l'esecuzione del codice con la funzione calculate_factorial(). La finestra Call Stack mostra lo stack delle chiamate alle funzioni in ordine inverso con l'ultima chiamata in cima alla lista:

  9. Premi F7 per avanzare all'interno del ciclo. Osserva i valori delle variabili nella finestra Variables.

  10. Quando sei sicuro che il codice lavori correttamente, premi Ctrl-F7/⌘-F7 per annullare l'esecuzione passo passo della funzione. Il programma ritorna alla linea successiva la chiamata di functioncalculate_factorial().
    Nota: In alternativa, puoi premere F7 finché il programma completa l'esecuzione della funzione calculate_factorial(). Torni comunque alla chiamata successiva a quella della funzione.

  11. Avendo appena controllato la funzione calculate_factorial() e sapendo che lavora correttamente, puoi saltare la sua esecuzione ("step over"). Per saltare l'esecuzione passo passo, premi F8. Il programma si ferma alla chiamata della funzione calculate_sum().

  12. Per entrare nella funzione calculate_sum(), premi F7.
  13. Per sorvolarla, premi F8. In entrambi i casi il debugger si ferma all'ultima linea della funzione calculate_sum_of_factorials().

  14. Premi F7. Il debugger si sposta alla linea con l'istruzione echo.
  15. Premi F7 provoca l'uscita dal programma La finestra del browser si apre e mostra il risultato dell'esecuzione:

Utilizzare Watches Aggiuntivi

Puoi definire watches aggiuntivi per seguire l'esecuzione del programma. Ciò può aiutarti ad intercettare un errore.
Avvertimento: Impostare Watches aggiuntivi destabiliza XDebug. I Watches sono disabilitati per default nelle opzioni di debug.
  1. Aggiorna il codice come segue (Sostituisci un più con un meno):
    function calculate_sum ($argument1, $argument2) {
        return $argument1 - argument2;
          }
     
    Supponi che ci sia un errore di battitura e tu abbia bisogno di calcolare la somma.
  2. Scegli Debug > New Watch o premi Ctrl/⌘-shift-F7. La finestra New Watch si apre.
  3. Inserisci la seguente espressione e clicca OK.
    $factorial1+$factorial2
    La nuova espressione appare nella finestra Watches.
  4. Avvia la sessione di debug. Quando il debugger si ferma alla linea
    return $result;
    confronta il calore dell'espressione nella finestra Watches e il valore di $result nella finesta Local Variables. Dovrebbero essere uguali ma differiscono.

Questo esempio è estremamente semplice al fine di fornire delle informazioni generali sull'uso dei Watches.

Casi in cui PHP e HTML sono Mescolati

Puoi fare il debug di codice che contiene sia blocchi HTML che PHP. Nell'esempio dalla sezione precedente i valori sono inseriti direttamente nel codice. Espandi il codice on una modulo di input HTML per inserire i valori.
  1. Aggiungi il seguente codice HTML sopra il blocco <?php ?> :
     <form action="index.php" method="POST">
           Enter the first integer, please:
           <input type="text" name="first_integer"/><br/>
           Enter the second integer, please:
           <input type="text" name="second_integer"/><br/>
           <input type="submit" name="enter" value="Enter"/>
    </form>
  2. sostituisci le seguenti linee all'inizio del blocco <?php ?> :
    $m=5;
       $n=10;
         $sum_of_factorials = calculate_sum_of_factorials ($m, $n);
         echo "The sum of factorials of the entered integers is " . $sum_of_factorials;
    con il seguente codice:
    if (array_key_exists ("first_integer", $_POST) && array_key_exists ("second_integer", $_POST)) {
    
        $result = calculate_sum_of_factorials ($_POST["first_integer"], $_POST["second_integer"]);
    
        echo "Sum of factorials is " . $result;
    
    }
  3. Imposta un breakpoin all'inizio del blocco <?php ?> e avvia la sessione di debug.
  4. Premi F7. Il debugger percorre il programma. La finestra del browser si apre ma il modulo di input non è visualizzato. Questo è il comportamento corretto del debugger perché deve attraversare l'intero codice sorgente della pagina web prima che la pagina possa essere visualizzata. Praticamente, il debugger attraversa il codice due volte. La prima volta elabora il codice per visualizzare il modulo di input HTML. La seconda volta esegue il codice PHP passo per passo.
  5. Premi F7 fino a raggiungere la fine del programma e apri il modulo di input si apre.
  6. Compila il modulo e clic Enter. La sessione di debug continua come descritto nella sezione "Esempio di Sessione di Debug". 

Mappatura, Debugger Proxy e Avvio della Sessione di Debug su un URL Personalizzato

E' possibile fare il debug sia di script che di pagine web, e delle pagine web può essere fatto il debug sia localmente che remotamente. Per il Debug Remoto, sfortunatamente il file php sottoposto a debug non è lo stesso file aperto sulla macchina locale che esegue l'IDE. Il supporto del Dubugger in NetBeans deve poter mappare i percorsi del server su percorsi locali. Comunque, a causa delle troppe complicazioni, la mappatura non può essere risolta automaticamente per ogni singolo scenario. Perciò, a partire da NetBeans 6.7 puoi definire manualmente la mappatura attraverso le impostazioni del progetto per ogni configurazione di esecuzione. Puoi anche specificare il proxy server, se c'è, e l'URL su cui avviare la sessione di debug. Se non specifichi questo URL, il debug parte sul file index.
Per impostare la mappatura del percorso e abilitare il debug di URL personalizzati:
  1. Clic destro sul nodo del progetto nella finestra Projects e apri Properties del menu contestuale del progetto.
  2. Nella finestra di dialogo Project Properties, vai alla categoria Run configuration.
  3. Clicca il pulsante Advanced. Si apre la finestra di dialogo Adevanced Web Configuration.
  4. Aggiungi il percorso del server e il percorso del progetto per la mappatura del percorso.
  5. Sotto "Debug URL", seleziona una delle seguenti voci (non lasciare selezionato il valore di default):

    • Ask Every Time, che fa chiedere ti fa chiedere dall'IDe l'URL quando avvii una sessione di debug.
    • Do Not Open Web Browser, che richiede che tu apra il browser e inserisca l'URL manualmente (hai bisogno della variabile GET/POST XDEBUG_SESSION_START).
  6. Se utilizzi un server proxy per il debug, inserisci l'host name del server e la porta nella sezione Debugger Proxy.
Per maggiori informazioni, vedi Path Mapping in PHP Debugger nel blog di NetBeans per PHP.

Articolo originale http://netbeans.org/kb/docs/php/debugging.html