Configurer Xdebug pour déboguer dans PhpStorm 2017 / 2018

PhpStorm est un environnement de développement intégré (IDE) très populaire. Il le doit à ses fonctionnalités et à son ergonomie, ainsi qu'à son excellent rapport qualité / prix. En effet, il vous en coûtera moins de 90 € pour une licence perpétuelle avec mise à jour durant un an (vous pouvez aussi opter pour une formule de licence renouvelable automatiquement pour bénéficier de mises à jour au-delà de cette durée) et... beaucoup moins, voire rien du tout dans bien des cas : si vous êtes étudiant / enseignant, ou si vous travaillez sur un projet Open source.
Comme tout IDE, PhpStorm peut se révéler un peu déroutant pour le développeur qui le découvre, surtout si ce dernier n'a jamais beaucoup programmé de sa vie. En particulier, comment s'y prendre pour déboguer une application PHP, c'est-à-dire contrôler pas-à-pas l'exécution d'un script PHP initiée par une action de l'utilisateur sur l'interface utilisateur (UI) de l'application en question, c'est-à-dire une page Web ?
Pour y parvenir, il faut installer une extension de PHP, modifier le fichier de configuration de ce dernier, installer une extension dans Firefox. Et créer la configuration de débogage de PhpStorm, direz-vous ? C'est la bonne surprise : il n'y en pas ! Passage en revue de toutes les étapes à suivre pour y arriver.
Une session de débogage avec Xdebug dans PhpStorm
Mise à jour du 21/02/2019 : Explication d'une erreur commune No debug extension is loaded.

Le Web pour le développeur ? Une régression !

Il faut bien reconnaître la cruelle réalité : du point de vue du développeur, le Web a constitué une régression incroyable. En fait, ce système d'échange entre un client et un serveur n'a pas du tout été conçu pour permettre au client d'accéder à une application, mais à des documents. Partant, alors que beaucoup avait été accompli en matière de développement d'applications client-serveur, il a fallu tout réinventer, tout particulièrement des environnements de développement intégrés (IDE) permettant de développer des applications avec la même aisance que s'il s'agissait d'applications fonctionnant uniquement sur le client. Passons sur les discussions sans fin que cela a pu occasionner sur le partage de tâches entre le client et le serveur et les enjeux de sécurité incidents...
Pendant longtemps, le débogage des applications Web n'a pas trouvé de solution. C'est que l'architecture était plutôt complexe. Qu'on y songe : un navigateur exposant une interface HTML permettant d'exécuter un script sur un serveur HTTP, aucun des deux n'étant conçu pour s'intégrer avec un IDE qui permettrait au développeur de contrôler cette exécution. Comment faire, sinon en mobilisant la recette préhistorique consistant à polluer le script d'instructions permettant d'exercer ce contrôle, c'est-à-dire intégrer les fonctionnalités du débogage dans le code à déboguer ? Et que je te rajoute des echo () pour afficher dans le navigateur ce qui se passe sur le serveur, des <input type=button> pour générer des requêtes intermédiaires au serveur depuis le navigateur, etc.
Avec le recul des années, le développeur est ici encore bien forcé de constater, en soupirant, qu'en informatique, on innove moins qu'on rénove. Enfin, un quart de siècle après les débuts du Web, la lumière semble au bout du tunnel. Même si la solution présentée ici n'est pas évidente à mettre en oeuvre, elle constitue pour le développeur un progrès considérable. Il va enfin pouvoir déboguer une application Web comme il avait pu prendre l'habitude de déboguer un programme... en assembleur sur Amiga 500. Le médiéval redevient contemporain ; on était retourné à la préhistoire, je vous dis !

Un projet de base à déboguer dans PhpStorm

Pour tout ce qui suit, il est nécessaire d'avoir installé un serveur Apache et PHP. Si vous ne l'avez pas déjà fait, reportez-vous à ici pour découvrir comment procéder.
Commençons par le commencement. Démarrez PhpStorm, et cliquez sur Create New Project pour créer un nouveau projet de type PHP Empty Project logé dans le répertoire racine de notre serveur. N'oubliez pas de spécifier la version de PHP que vous comptez utiliser. Inutile de spécifier un interpréteur. Cliquez sur Create.
Création d'un projet de base
Dans le volet de gauche, cliquez du bouton droit sur le projet, et sélectionez PHP File. Nommez ce fichier index. PhpStorm crée le fichier index.php, qui s'affiche pour édition.
Saisissez simplement code suivant, qui consiste à simplement afficher Hello, world! dans la page du navigateur du client :
<?php
echo ("Hello, world!");
?>
Enregistrez tout cela, puis rendez-vous dans Firefox pour accéder au script via http://localhost/test (sur l'image, le script est placé sur un serveur virtuel de développement qui écoute sur le port 81, mais peu importe). Vous devriez voir le message s'afficher.
Test de index.php
De retour dans PhpStorm, vous pouvez cliquer dans la marge de l'instruction echo () pour faire apparaître un point orange, qui indique que vous venez de positionner un point d'arrêt (breakpoint). Vous venez d'indiquer à PhpStorm que vous souhaitez que l'exécution du script s'arrête à cet instant pour que vous puissez contrôler la suite.
Un breakpoint
Toutefois, si vous souhaitez déboguer, vous êtes mal barré. Comme vous pouvez le constater, les outils de débogage sont tous grisés dans la barre d'outils, sauf un étrange téléphone :
Les outils de débogage, pour l'heure désactivés
Comment faire ?

Xdebug, c'est quoi ?

En matière de débogage, PhpStorm a de quoi égarer n'importe qui. La liste déroulante qui apparaît dans la barre d'outils mentionnée à l'instant permet de sélectionner une configuration de débogage, sans laquelle rien n'apparaît possible. Pour créer une telle configuration, vous devez vous rendre dans le menu Run et sélectioner Edit Configurations.... Vous tombez alors sur une boite de dialogue parfaitement incompréhensible où un bouton + vous permet de sélectionner un type de configuration à créer parmi lesquelles vous ne sauriez choisir : PHP Built-in Web Server, PHP Script, etc.
Le bordel des configurations de débogage...
Tout cela est très intéressant mais, fort heureusement, vous allez pouvoir vous en passer totalement. En effet, Xdebug, c'est quoi ?
Dans cette configuration (qui n'en est donc pas une), le navigateur accède au script, ce qui déclenche le débogage dans PhpStorm. Le débogage est donc classique, c'est-à-dire que l'exécution du script est initiée par des actions de l'utilisateur sur l'UI de l'application.
Pour déboguer, il faut avoir installé un moteur de débogage (debugging engine), les plus connus (et peut-être les seuls ?) étant Xdebug et Zend debugger. Ici, c'est Xdebug qui sera retenu.
Un tel moteur fonctionne sur le principe suivant. Un serveur Xdebug est créé. Il contrôle l'exécution de PHP. Ce serveur communique avec ses clients (qui écoutent par défaut sur le port 9000) à l'aide d'un protocole spécifique au débogage, DGBP. A partir de là :
  • le moteur crée un session de débogage ;
  • il se connecte à un IDE qui écoute sur le port 9000 (en fournissant entre autres informations un paramètre identifiant l'IDE, IDE KEY) ;
  • il attend sagement les commandes (format ASCII) de l'IDE pour exécuter le programme et renvoie un résultat (format XML).
Les commandes de base sont toutes celles qu'on suppose permettre d'échanger avec un moteur, comme status (récupérer l'état de l'exécution) ou feature_get (récupérer des informations sur des fonctionnalités du moteur), et toutes celles qu'on suppose permettre de contrôler un débogueur, comme run (démarrer ou continuer l'exécution), step_into (exécuter jusqu'à l'instruction suivante), breakpoint_set (positionner un point d'arrêt), stack_get (récupérer le contenu de la pile d'exécution), etc.
Pour déboguer une application, il faut pouvoir simuler les actions de l'utilisateur de l'application et interrompre l'exécution durant le traitement de ces actions. La question qui se pose est : comment activer et désactiver le moteur Xdebug depuis le client de l'application PHP développée, c'est-à-dire non pas depuis l'IDE PhpStorm, mais depuis le navigateur Firefox ?
La réponse est : grâce à une extension de Firefox (Xdebug Helper) qui va rajouter à la requête au script PHP les paramètres qui permettent à Apache de savoir si Xdebug doit prendre le contrôle de l'exécution du script dans le cadre d'une session de débogage (XDEBUG_SESSION_START) ou non (XDEBUG_SESSION_STOP).
Quand le débogage est ainsi activé, Xdebug échange donc avec PhpStorm. Ainsi, si un point d'arrêt a été positionné dans le code du script dans PhpStorm, Xdebug va suspendre l'exécution, en informer PhpStorm, lequel va s'afficher devant le navigateur pour permettre au développeur de continuer à contrôler l'exécution depuis son interface.
En fait, Xdebug Helper permet de contrôler le moteur plus agréablement que des liens qu'il faut autrement rajouter à la barre de menu personnelle de Firefox, et qu'on peut générer à partir d'une page de JetBrains.
Par exemple, le lien permettant d'activer le moteur est (en supposant que IDE KEY est PHPSTORM) :
javascript:(/**%20@version%200.5.2%20*/function()%20{document.cookie='XDEBUG_SESSION='+'PHPSTORM'+';path=/;';})()

Installer Xdebug sur le serveur Apache

Cliquez ici pour télécharger la version TS (thread safe) x64 pour Windows. Cette version sera compatible avec la version d'Apache installée si vous avez suivi les instructions prodiguées ici.
Recopiez la DLL dans le répertoire ext de l'installation de PHP.
Editez alors la configuration de PHP (le fichier php.ini) pour activer l'extension :
[Xdebug]
zend_extension="php_xdebug-2.6.0-7.2-vc15-x86_64.dll"
xdebug.remote_enable=1
xdebug.remote_port="9000"
xdebug.profiler_enable=1
xdebug.profiler_output_dir="C:\Apache24\tmp"
Créez le répertoire C:\Apache24\tmp s'il n'existe pas.
Retournez dans PhpStorm. Dans File / Default Settings / Languages & Frameworks / PHP :
  • cliquez sur ... à côté de CLI Interpreter ;
  • cliquez sur + et sélectionnez Local Path to Interpreter ;
  • cliquez sur ... à côté de PHP executable et localisez php.exe dans le répertoire de PHP.
Configuration de l'interpréteur PHP en ligne de commandes
Le port par défaut est 9000.
Vérifiez que cela fonctionne. Dans Run / Web Server Debug Validation, indiquez le chemin au répertoire où PhpStorm doit créer le fichier de validation, et l'URL qui permet d'accéder au fichier en question, soit par exemple le même répertoire où réside le fichier index.php que vous avez créé. Cliquez sur Valider. PhpStorm vous affiche un bilan du test.
Résultats du test d'installation de Xdebug sur le serveur Apache
Si jamais PHPStorm rapporte une erreur No debug extension is loaded, c'est que PHP ne parvient pas à charger l'extension de Xdebug :
Echec du test d'installation de Xdebug sur le serveur Apache
Pour le vérifier, ouvrez une fenêtre de ligne de commandes, rendez-vous dans le répertoire d'installation de PHP - généralement C:\PHP7, et exécutez la commande php -version. En cas d'erreur, vous disposerez d'informations plus précises :
Analyse de l'échec de l'installation de Xdebug avec PHP en ligne de commandes
Ici, c'est que le fichier php.ini n'a pas été modifié, comme pourtant expliqué ici, pour indiquer où PHP peut trouver la DLL de Xdebug. Une fois la modification effectuée, cela marche beaucoup mieux en ligne de commandes... :
Validation de l'installation de Xdebug avec PHP en ligne de commandes
...et aussi dans PHPStorm !

Installer Xdebug Helper sur le navigateur Firefox

Cette étape ne vous coûtera pas beaucoup d'effort. Cliquez ici pour installer l'extension Xdebug Helper dans Firefox. C'est tout.

Déboguer le script PHP (ne requiert aucune configuration de débogage dans PhpStorm !)

De retour dans PhpStorm, sélectionnez Run / Start Listening for PHP Debug Connections. Vous pouvez aussi cliquer sur l'icône représentant un téléphone. Dès lors, PhPStorm écoute Xdebug sur le port 9000.
Depuis Firefox, rendez-vous à l'adresse du script index.php que vous avez créé. Cliquez alors sur l'icône de Xdebug Helper qui apparaît dans la barre d'adresse sous la forme d'un insecte gris, et sélectionnez Debug dans le menu déroulant.
Activer Xdebug depuis Xdebug Helper dans Firefox
Rechargez la page. PhpStorm apparaît, bloquant l'exécution au point d'arrêt que vous aviez spécifié.
Une session de débogage avec Xdebug dans PhpStorm
Il suffit de sélectionner Disable dans le menu de Xdebug Helper pour que le point d'arrêt ne soit plus respecté, quoi qu'il demeure activé dans PhpStorm. Cela permet de désactiver le débogage pour un script donné. Côté PhpStorm, il suffit de cliquer sur l'icône représentant un téléphone pour que PhpStorm cesse de dialoguer avec Xdebug et donc désactiver le débogage pour tout script.
Configurer Xdebug pour déboguer dans PhpStorm 2017 / 2018