Xdebug : Installation et premier pas

24 mars 2010Xdebug, debug, php
 Cet article a été rédigé il y a plusieurs années et peut ne plus être tout à fait à jour…

Je vois encore beaucoup trop souvent des installations de postes de développement PHP qui n'incluent pas l'extension Xdebug -- alors que je ne connais pas grand monde qui l'ait installée et soit ensuite revenu en arrière.

Cet article va nous permettre de voir :

  • Ce qu'est l'extension Xdebug
  • Comment installer l'extension Xdebug,
    • Sur une machine Linux
    • Et sur une machine Windows
  • Quelques petites choses que nous gagnons, une fois Xdebug installée et activée.

Il sera suivi d'un autre article, au cours duquel nous verrons que, combinée à un IDE moderne, Xdebug permet d'effectuer du débuggage d'application PHP en environnement graphique.

Note : Les exemples présentés ici ont été testés exclusivement sous PHP 5.3[1].


Sommaire :


Xdebug, mais qu'est-ce que c'est ?

Pour faire bref, Xdebug est une extension PHP, développée en C, qui facilite le développement et le débuggage de scripts et d'applications PHP, en fournissant un ensemble d'informations lors de leur exécution.
Pour n'en citer quelques unes :

  • << Stack Traces >> en cas d'erreur ou d'exception, affichant :
    • toute la pile d'appels de fonctions menant à l'erreur, permettant de plus facilement reconstituer le chemin qui a mené à l'erreur,
    • ainsi que l'ensemble des paramètres passés à ces fonctions.
  • Informations de profiling, permettant de mesurer combien de temps a été passé dans chaque fonctions appelées durant la construction d'une page, en vue de déterminer lesquelles de ces fonctions méritent notre attention lors de la phase d'optimisation de notre application.
  • Analyse de couverture de code : indique quelles portions de notre code ont été exécutées, et lequelles ne l'ont pas été -- particulièrement utile pour déterminer si nos tests unitaires couvrent ou non une part importante de notre code.

Quelques informations complémentaires :


Installation de Xdebug

Xdebug s'installe comme n'importe quelle autre extension PHP -- ce qui, à peu de chose près signifie << facilement >> sous Linux, et << ça dépend si vous avez de la chance >> sous Windows ^^


Installation de Xdebug sous Windows

En l'occurrence, pour ce qui est de Xdebug sur une machine Windows, vous avez, globalement de la chance : la page de téléchargement de Xdebug vous permet de télécharger l'extension pré-compilée.

Plusieurs versions sont téléchargeables :
Note : téléchargez directement depuis le site officiel, pour être certain d'avoir la toute dernière version !

  • 5.2 VC6 Non-thread-safe (32 bit)
  • 5.2 VC6 (32 bit)
  • 5.3 VC6 Non-thread-safe (32 bit)
  • 5.3 VC6 (32 bit)
  • 5.3 VC9 Non-thread-safe (64 bit)
  • 5.3 VC9 Non-thread-safe (32 bit)
  • 5.3 VC9 (64 bit)
  • 5.3 VC9 (32 bit)

Entre PHP 5.2 et PHP 5.3, à vous de choisir en fonction de la version de PHP avec laquelle vous travaillez -- si vous utilisez une version plus ancienne, ou même PHP 4, il est plus que temps de vous mettre un peu à jour !

Entre 32 bits et 64 bits, ici encore, le choix est relativement simple, et vous êtes le mieux placé pour savoir quelle version prendre.

Reste ensuite, pour la version PHP 5.3, à choisir entre :

  • VC6 Non-thread-safe
  • VC6
  • VC9 Non-thread-safe
  • et VC9

Si on en croit windows.php.net :

  • Si vous utilisez PHP avec les binaires Apache 1 ou Apache 2 téléchargés depuis apache.org, vous devez utiliser la version VC6 -- C'est probablement votre cas.
  • Si vous utilisez PHP avec IIS, vous devriez utiliser la version VC9.

Et pour ce qui est de Thread-safe vs Non-thread-safe : la version que vous choisirez doit correspondre à la version de PHP que vous utilisez.

Une fois le bon fichier .dll téléchargé, placez-le dans le répertoire d'extensions de votre installation de PHP.
(Variable, en fonction de la manière dont vous avez installé PHP ; mais une bonne indication est qu'il y a pas mal d'autres .dll dans ce répertoire, dont, probablement, par exemple; php_mysql.dll ou php_soap.dll).


Et, puisque nous parlons d'installation d'extensions PHP sous Windows, et que la question revient souvent : vous pouvez télécharger quelques extensions << populaires >> (Entre autres : APC, geoip, memcache, oauth, ...), pré-compilées pour windows, depuis http://downloads.php.net/pierre/[2].


Installation de Xdebug sous Linux

Sous Linux, où nous disposons traditionnellement d'outils de développement permettant la compilation de composants développés en C, nous passerons par la compilation de l'extension -- de la sorte, nous aurons la version qui correspond le mieux à notre environnement.

Heureusement, pas besoin de tout faire << à la main >> : utiliser la commande pecl va permettre d'automatiser tout le processus.

Donc, pour installer Xdebug, comme pour à peu près n'importe quelle autre extension PECL :

pecl install xdebug

Notez que cette commande devra probablement être lancée avec un compte root, ce qui peut signifier, sous une distribution telle Ubuntu, devoir utiliser sudo :

sudo pecl install xdebug

Le processus devrait passer par les différentes étapes de l'installation de l'extension :

  • Téléchargement des sources
  • Configuration
  • Compilation
  • Et enfin, installation

Notez qu'il vous faudra ensuite activer l'extension, en modifiant votre fichier php.ini -- mais n'ajoutez pas la ligne d'extension que vous indique la commande pecl en fin d'exécution !


Un peu de configuration

Maintenant que nous avons installé l'extension en elle-même, il va falloir l'activer, et, éventuellement, la configurer.

Activer l'extension Xdebug

L'activation de l'extension Xdebug se fait en ajoutant une ligne au fichier php.ini, ligne permettant de charger l'extension.

Cette ligne aura la forme suivante :

zend_extension=CHEMIN_ABSOLU_VERS_L_EXTENSION

Par exemple, sur une machine Linux :

zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20090626/xdebug.so

Trois points à noter :

  • Pour PHP <= 5.2, il peut être nécessaire d'utiliser zend_extension_ts à la place de zend_extension, si votre installation est Thread-safe.
  • Il faut utiliser la directive zend_extension, et pas extension tout court.
    • Et ce même si la commande pecl vous dit d'utiliser extension !
  • Le chemin indiqué doit être un chemin absolu, et non relatif.


Quelques options de configuration

Maintenant que l'extension Xdebug est chargée, il peut être utile de modifier quelques points de configuration.

Tout d'abord, rappelons que nous mettons en place un environnement de développement, et pas un serveur de production ! Cela signifie qu'il est intéressant d'afficher les messages d'erreurs, par exemple -- chose que nous ferions absolument pas sur un environnement ouvert au public.

Configuration de directives non spécifiques à Xdebug

Pour commencer, voici deux directives de PHP qu'il faudra configurer dans le fichier php.ini[3] votre environnement de développement :

display_errors = On
html_errors = On

La première directive, display_errors, entrainera l'affichage à l'écran des messages d'erreurs, et la seconde, html_errors, permettra leur présentation enrichie en HTML.

Xdebug a besoin que ces deux directives soient activées pour pouvoir enrichir un peu plus les affichages obtenus.

Configuration de directives spécifiques à Xdebug.

Xdebug fournit un grand nombre d'options de configuration, que vous pouvez retrouver dans la documentation. La plupart de ces directives ont une valeur par défaut appropriée pour un usage commun, mais voici néanmoins les quelques lignes de configuration que j'ai tendance à ajouter à mon fichier php.ini[4] :

; Enrichir l'affichage obtenu lors des appels à la fonction var_dump
; Activée par défaut
xdebug.overload_var_dump = 1

; Configure les quantités de données affichées par la fonction var_dump
xdebug.var_display_max_children = 128
xdebug.var_display_max_data = 1024
xdebug.var_display_max_depth = 8

; Configure les données affichées dans les stack traces
xdebug.collect_includes = 1     ; Noms de fichiers
xdebug.collect_params = 2       ; Paramètres de fonctions / méthodes

; Si activée, affiche une stack trace à chaque fois qu'une exception est levée
; (Même si elle est catchée)
; => Je désactive généralement cette directive,
; mais la conserve présente pour pouvoir la réactiver "si besoin"
xdebug.show_exception_trace = 0

; Le nombre maximal de profondeur d'appels de fonctions
; (Sécurité contre les récursions infinies)
xdebug.max_nesting_level = 64

Bien entendu, un grand nombre d'autres options sont disponibles, mais celles-ci sont généralement largement suffisantes -- et encore, j'ai été généreux !
(Du moins, lorsque l'on se limite aux fonctionnalités de base de Xdebug ; ce qui est volontairement le cas pour cet article.)


Une fois Apache redémarré, vous devriez voir apparaitre un bloc de ce type en sortie de phpinfo(), prouvant que Xdebug est activée :

xdebug-phpinfo-1.png


Xdebug : notre vie en est facilitée !

Une fois l'extension Xdebug installée, activée, et configurée, il ne nous reste plus qu'à profiter des fonctionnalités qu'elle apporte.

Affichage de variables : var_dump

Bien souvent, nous avons besoin d'afficher le contenu de variables -- c'est probablement le moyen le plus simple de savoir ce qu'elles contiennent, après tout.

Pour exemple, considérons une variable un peu complète / complexe, qui pourrait être déclarée de la manière qui suit :

$data = array(
    'hello, world!',
    array(
        'sub-1', 'sub2',
        'sub-3' => (object)array('glop', 'test'),
    ),
    (object)array(
        'plop' => 'super gut !',
        'toto' => simplexml_load_string(<<<A
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <user id="1">
        <firstname>Pascal</firstname>
        <lastname>MARTIN</lastname>
    </user>
    <user id="2">
        <firstname>Anon</firstname>
        <lastname>YMOUS</lastname>
    </user>
</root>
A
),
    )
);

Vouloir afficher son contenu se traduit généralement par ce genre de portion de code, utilisant la fonction PHP print_r :

echo '<pre>';
print_r($data);
echo '</pre>';

Et le résultat obtenu ressemble à ceci :

print_r-1.png

OK, c'est à peu près acceptable, mais :

  • Ca fait trois lignes de code ^^
  • print_r ne fait pas de distinction, à l'affichage, entre false, null, '', ...
  • Plus la variable utilisée est de taille important, plus l'affichage devient difficile à lire.


On peut aussi envisager d'utiliser la fonction var_dump :

echo '<pre>';
var_dump($data);
echo '</pre>';

Un peu plus d'informations seront affichées, mais, de base, le résultat ne sera pas encore parfait...


Cela dit, maintenant que l'extension Xdebug est activée, elle surcharge la fonction var_dump fournie par PHP, en vue d'améliorer son affichage, et de rajouter quelques limites (notamment, pour éviter d'afficher tout le contenu d'éléments de taille trop importante, ou de tableaux ayant trop de niveaux de profondeur).

Et donc, en utilisant une seule ligne de code :

var_dump($data);

Voici le résultat obtenu :

xdebug-var_dump-1.png

N'est-ce pas tout de suite plus agréable[5] ?


Stack-Traces en cas d'erreurs et/ou exceptions

L'autre fonctionnalité que l'installation et l'activation de Xdebug nous apporte sans le moindre effort est l'amélioration des messages affichés en cas d'erreurs ou d'exceptions.

Pour exemple, considérons le fichier stack-trace-1/temp.php, reproduit ci-dessous :

<?php
// stack-trace-1/temp.php

require 'temp-2.php';

function my_function($param) {
    $obj = (object)array(
        'param' => $param,
        'boo' => 'lette',
    );
    $a = new ClassA();
    $a->method($obj);
}

my_function('test');

Qui fait appel au fichier stack-trace-1/temp-2.php, dont le contenu est le suivant :

<?php
// stack-trace-1/temp-2.php

class ClassA {
    public function method($data) {
        $this->_anotherMethod($data);
    }
    protected function _anotherMethod($data) {
        throw new Exception('test');
    }
}

Typiquement, sans Xdebug, utiliser ces deux portions de code mènerait à l'obtention d'un message d'erreur de ce genre :

stack-trace-exception-no-xdebug-1.png

Mais, maintenant que nous avons installé et activé l'extension Xdebug, nous obtenons quelque chose qui ressemble plus à ceci :

xdebug-stack-trace-exception-1.png

Autrement dit :

  • Nous avons une meilleure présentation de la stacktrace -- et plus un gros pâté de texte quasi-brut !
    • OK, j'admet, c'est moins discret : l'orange se voit de loin ^^
  • Les arguments passés à chaque fonction sont présentés
  • Nous pouvons passer la souris dessus pour voir leur contenu
  • Nous avons des indications au niveau de la mémoire utilisée


Et la différence est encore plus visible pour une erreur que pour une Exception.

Par exemple, si nous remplaçons le contenu de notre fichier temp-2.php, déjà présenté plus haut, par quelque chose qui ressemble à ceci :

<?php
// stack-trace-2/temp-2.php

class ClassA {
    public function method($data) {
        $this->_anotherMethod($data);
    }
    protected function _anotherMethod($data) {
        // Moyen simple de causer une Fatal Error ^^
        $a = (object)array();
        echo $a['test'];
    }
}

Le résultat obtenu sans Xdebug ressemble à ceci :

stack-trace-erreur-no-xdebug-1.png

Autrement dit, nous n'avons rien de plus que le type d'erreur, le nom du fichier où elle se produit, et le numéro de la ligne... Alors qu'avec Xdebug, nous obtenons ceci :

xdebug-stack-trace-erreur-1.png

Ici encore, est-ce que le simple fait d'installer Xdebug n'est pas intéressant[6] ? ;-)


Voila qui marque la fin de la première partie de cet article.

Pour la seconde partie[7], nous verrons que Xdebug nous apporte bien plus que ces petites améliorations : Xdebug nous permettra de débugger nos applications, en interface graphique, directement depuis notre IDE -- Eclipse PDT, en l'occurrence.


Notes

[1] En théorie, il ne devrait pas y avoir de différence (majeure, tout au moins) entre PHP 5.2 et PHP 5.3 pour ce que je présente ici -- mais travailler avec PHP 5.3 sur ce blog est aussi un peu ma manière d'essayer de le rendre plus populaire ; et donc, d'avoir plus de chances de bosser avec, dans un futur moins lointain ;-)

[2] http://downloads.php.net/pierre/ fait office d'espace de téléchargement d'extensions pour windows, en attendant que celles-ci soient transferrées vers http://windows.php.net/

[3] Ou dans votre Virtual Host, ou ailleurs -- tant que cette configuration s'applique au site sur lequel vous travaillez

[4] Même si certaines directives correspondent aux valeurs par défaut, les inclure a l'avantage d'être clair -- et le jour où vous voudrez les désactiver, vous saurez comment elles s'appellent !

[5] Rien qu'avec ça, j'ai déjà convaincu pas mal de monde d'installer Xdebug sur leur poste de développement ^^

[6] Avec ça aussi, j'ai convaincu pas mal de monde d'installer Xdebug sur leurs machines de dev^^

[7] En cours de rédaction, ce qui signifie que je peux la publier dans une semaine comme dans deux mois