Debugger une application PHP se résume souvent à coller des error_log un peu partout dans le code. Mais lorsque le dit code commence à passer une taille critique, cette option devient vite ingérable. C'est là qu'intervient Xdebug, le concurrent libre du debugger de Zend.
Eclipse/PDT et Apache/PHP/XDebug
Pour traquer les cafards, nous allons tout d'abord utiliser Eclipse (3.4 aka Ganymede) et l'excellent plugin PDT (2.x dev).
Une fois le plugin en place, il reste à ajouter Xdebug à la votre plate-forme de test. Je pars du principe qu'Apache et PHP sont déjà installés et que le serveur est en écoute quelque part sur le réseau.
Paramétrage du serveur
Installer XDebug n'est pas bien compliqué, il y a de très fortes chances qu'il soit déjà inclus dans votre distribution. Sous Mandriva, cela passe donc simplement par un urpmi php-xdebug. Sur les debian-like j'imagine qu'un coup d'apt-get ne doit pas tomber très loin.
Une fois le paquet en place, reste à configurer PHP pour qu'il utilise cette nouvelle extension. Toujours sous Mandriva, cela se passe dans le fichier /etc/php.d/A29_xdebug.ini. Là nous allons rechercher une série de variables suivantes à modifier :
xdebug.remote_autostart = Off
xdebug.remote_enable = On
xdebug.remote_host = 10.0.0.10
xdebug.remote_port = 9000
xdebug.remote_handler = "dbgp"
Le principe de XDebug est un peu troublant au démarrage. Lorsqu'éclipse lance le debuggage d'une page, il ouvre au préalable un serveur XDebug sur le port 9000. Lorsqu'Apache affiche la page, le plugin php-xdebug prend la main et cherche à se connecter sur ce serveur. c'est la que le debuggage commence. Du coup, il est nécessaire de spécifier dans A29_xdebug.ini l'adresse IP de la machine sur laquelle tourne eclipse, ici nous avons 10.0.0.10, à remplacer donc par la votre. Si vous travaillez uniquement en local, vous pouvez remplacer cela par localhost.
Maintenant, juste un petit coup de redémarrage d'apache et nous pouvons retourner sous Eclipse.
Paramétrage d'eclipse
Là encore, quelques réglages sont nécessaires. Déjà il nous faut configurer un navigateur par défaut. Pour cela, faite un tour dans Windows/Préférences (me demandé pas pourquoi ils ont clocké ça là dedans...), General/Web Browser. Là vous ajouterez votre navigateur préféré en prendrez soin de le cocher une fois l'opération réalisée pour le rendre actif par défaut.
Ne partez pas tout de suite, et allez dans la section PHP/Debug. Là vous pouvez sélectionner xdebug et clicker sur Configure, histoire de vérifier que le host est bien localhost et le port 9000, comme nous l'avions configuré pour PHP.
Voilà, vous pouvez clicker sur OK pour valider ce paramétrage.
Maintenant, il ne nous reste plus qu'à lancer l'application en mode déverminage par Run/Debug As/PHP Web Page. Comme c'est un nouveau lancement, on vous demande une URL qui est généralement fausse. Remplacez cela par celle de la page à tester. Une fois validée, le navigateur s'ouvre et l'exécution s'arrête brutalement sur le première ligne du premier script PHP. Après c'est du classique, vous avez accès au pas à pas (F6), aux points d'arrêt, à la visualisation des variables par survol, l'ajout d'expressions watch, etc...
Analyse de performances
L'intérêt de Xdebug ne s'arrête pas au debuggage, loin de là. C'est aussi un formidable outil d'analyse de performance (profiling). Pour activer ce mode, il faut retourner dans le fichier de configuration de Xdebug pour modifier comme suit :
xdebug.profiler_append = Off
xdebug.profiler_enable = On
xdebug.profiler_enable_trigger = Off
xdebug.profiler_output_dir = /tmp
xdebug.profiler_output_name = php_profile.txt
Attention, cette fois il est très claire qu'activer cela nuit gravement aux performances. Activez et désactivez donc xdebug.profiler_enable selon vos besoins.
Une fois le serveur Apache redémarré, il ne vous reste plus qu'à aller faire un tour sur la page qui explose les compteurs de temps. Quant vous avez terminé, retournez voir dans le dossier /tmp où devrait se trouver un php_profile.txt, c'est lui qui contient tous les temps d'exécution enregistrés par Xdebug.
Pour visualiser le résultat, malheureusement il n'existe pas (à ma connaissance) d'application GTK. Mais il y a néanmoins le très bon kcachegrind qui permet une exploration précise et rapide des temps d'exécutions.
Conclusion
Xdebug fait à mon sens parti de la trousse à outil de base lorsque l'on porte sa casquette de développeur (ou pompier
PHP. Il n'empêche pas de coller nos error_log de base mais aide énormément lorsque l'application patine ou qu'un algo part en vrille.
| Fichier attaché | Taille |
|---|---|
| kcachegrind.png | 36.27 Ko |
Merci pour l'article. Ces "manips" deviennent de plus en plus faciles.
Cela dit, ne faut-il pas lier l'usage d'un débuggeur à l'écriture de tests ? (test driven development)
Je ne le fais pas systématiquement personnellement, mais qu'en pensez-vous ?
@Philippe
Les manips deviennent de plus en plus faciles
Oui, j'avoue que PDT change la vie sur ce point. La prise en charge native du protocole dbgp rend tout cela d'une facilité déconcertante.
Cela dit, ne faut-il pas lier l'usage d'un débuggeur à l'écriture de tests ? (test driven development)
Je ne le fais pas systématiquement personnellement, mais qu'en pensez-vous ?
Non, ce n'est pas une nécessité, loin de là, en tout cas à mon humble avis. Le debuggeur est un outil de mise au point qui est transversal à toute méthode de développement. Difficile de s'en passer quelle que soit l'approche de développement adoptée. En d'autre termes, le debuggeur permet de trouver la source d'une anomalie, les tests permettent de détecter l'anomalie elle-même.
Maintenant pour les tests automatisés eux-même (unitaires ou pas), ils sont un outil utilisé pour garantir (autant que faire ce peut) la non-régression et le respect des spécifications. Maintenant que le développement soit asservi aux tests (test driven) ou qu'ils soient fait à posteriori, c'est un débat proche de celui de la robe du Christ. Il y a de grand prêtres des méthodes "agile" qui sont intraitable sur ce point, pour moi c'est une question de contexte. La seule chose sure est qu'ils sont une nécessité et que les régles du jeu doivent être claires dés le départ du projet.
Après côté couverture et systématisme, il n'y a pas non plus obligation d'être un intégriste. La présence de tests est une nécessité qui varie selon les contextes. A titre d'exemple, si je prends les deux domaines classique d'une application, à savoir une couche présentation et une couche de traitements/stockage de l'information. Je vais avoir tendance à systématiquement ajouter des tests pour tous les les traitements et laisser à un véritable humain et son cerveau faire la recette de la partie présentation.
Enfin, pour être complet, pour qu'une application soit la plus fiable possible, ce n'est pas le tout de faire des tests unitaires. Il faut aussi prévoir l'imprévisible pour être capable de corriger rapidement et éventuellement de fixer la correction par un nouveau test. Pour cela, une application doit, en plus des tests, être capable de générer un volume suffisant de traces permettant de localiser précisément une anomalie imprévisible.
Mais dans tous les cas, j'aurais tout de même besoin à un moment ou à une autre d'un debugger
Voilà, j'espère que j'ai répondu à votre question.