-
Notifications
You must be signed in to change notification settings - Fork 5
HowTo xdebug
Disclaimer : ❗ Cette configuration ne doit pas être exposée sur internet ❗
Elle pose des problèmes de sécurité évidents. On installe ici cette architecture dans une VM qui n'est accessible QUE depuis le système hôte
On va installer tout le nécessaire pour créer un projet PHP qui sera hébergé plus tard sur le nom de domaine http://www.example.com. Prenons ce nom de domaine "éducatif" pour illustrer notre HowTo :
- c'est un domaine réservé à des démonstrations, qui ne peut pas être acheté
- ce nom de domaine pointe vers un hébergement réel quelque part dans le monde
- lorsque les crawlers visiteront ce howto, ils ne tomberont pas sur un domaine qui appartient à quelqu'un au hasard ; on ne participera pas au pagerank d'inconnus...
Sur notre machine locale, on va simuler le contrôle du domaine example.com , qui du point de vue de notre machine locale pointera vers notre VM. Pour tous les autres gens sur la planète, le domaine example.com pointera toujours vers l'hébergement réel du domaine.
Il est évident qu'il faut avoir suivi les HowTos dédiés pour construire la VM sur laquelle on va travailler : HowTo VirtualBox et HowTo LAMP.
Note : Les manipulations suivantes doivent être faites dans la VM
- On installe simplement le module xdebug avec apt :
sudo aptitude install php5-xdebug
Quelques liens pour en savoir plus sur xdebug sont donnés dans ce paragraphe.
On a besoin de configurer le module pour permettre du débug à distance ; en effet, les sources php testées se trouvent physiquement dans la VM. Le serveur web apache de la VM va devoir communiquer avec notre éditeur de texte local pour permettre le pas à pas. Le principe est expliqué grossièrement dans ce paragraphe.
-
Il faut ajouter des lignes au fichier
/etc/php5/apache2/conf.d/20-xdebug.ini, pour qu'il ressemble à ça :zend_extension=xdebug.so xdebug.remote_enable=1 xdebug.remote_host=127.0.0.1 xdebug.remote_connect_back=1 # Not safe for production servers xdebug.remote_port=9000 xdebug.remote_handler=dbgp xdebug.remote_mode=req xdebug.remote_autostart=true # Not safe for production servers xdebug.idekey=xdebug.atom
-
Puis on redémarre apache pour qu'il charge php avec notre module xdebug configuré :
sudo service apache2 restart
On pourrait examiner un phpinfo() pour retrouver les détails de la configuration de notre module xdebug

A ce stade on aboutit au stack logiciel suivant dans la VM :

Le module xdebug envoie ses messages durant l'éxécution des scripts php, mais aucun service n'écoute à l'adresse définie. Le service sera "branché" dans le paragraphe "tout brancher ensemble, plus bas
On a choisi l'éditeur de texte Atom, qui est configurable et open source. Il n'est pas disponible dans les dépôts d'ubuntu, il faut le charger depuis le site de l'éditeur : https://atom.io/
Sur la machine locale, on va augmenter l'éditeur de texte, pour qu'il fournisse les fonctionnalités de base d'un IDE. Voir la définition d'un IDE sur wikipedia
Pour l'installation des plugins Atom, on va utiliser l'outil disponible dans Atom lui-même, accessible via le menu 'Edit' -> 'Préférences' , puis l'onglet 'Install' à gauche de la fenêtre 'Settings' qui s'est ouverte.
-
On va créer, sur la machine locale, le dossier qui accueillera nos sources php qui seront versionnées par git :
mkdir ~/project_example.comNOTE : mon home est ici
/home/ben, le dossier sera créé à l'adresse/home/ben/project_example.com -
Et on va "donner" ce dossier à Atom, en tant que dossier de projet ; dans Atom menu 'file' -> 'add project folder', puis choisissez le dossier
project_example.comcréé ci-dessus dans votre home
Ce plugin va se charger de la synchronisation des sources php entre notre copie locale (versionnée par git), et la copie "testée" qui est servie par le apache de la VM. Le principe est brièvement expliqué dans ce paragraphe
On l'installe via l'outil interne d'Atom, comme dans la capture ci-dessous :

La configuration du module se fait par projet, le détail sera donné dans le paragraphe "tout brancher ensemble" plus bas.
Ce plugin fournit l'interface serveur du procéde de remote debug.
On l'installe via l'outil interne d'Atom, comme dans la capture ci-dessous :

On configure ce plugin globalement, principalement en lui donnant :
- le path map : on renseigne le plugin des chemins des sources php de part et d'autre. Autrement dit, on définit la correspondance entre :
- le chemin des sources php sur la machine locale ; la copie des sources qui sera éditée dans Atom et qui sera versionnée avec git
- le chemin des mêmes sources dans la VM ; la copie des sources qui sera éxécutée dans l'apache de la VM
- le port et éventuellement l'adresse du serveur de debug ; le port 9000 est le port par défaut, on laisse comme ça. L'adresse est 127.0.0.1 (localhost) par défaut.
Un exemple de configuration est représenté par la capture ci-dessous :

On aboutit à ce stade à l'architecture logicielle suivante du point de vue du système hôte :

Pour créer le nouveau VHOST dans le apache de la VM, on peut se reporter au HowTo dédié.
Ici, le nom de domaine sur lequel on va monter notre VHOST est example.com, et on va placer son DocumentRoot sur /var/www/example.com.
On aboutit au fichier /etc/apache2/sites-available/example.com.conf suivant :
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/example.com.error.log
CustomLog ${APACHE_LOG_DIR}/example.com.access.log combined
</VirtualHost>Ce fichier étant fourni, procédez à toutes les étapes décrites dans le HowTo dédié
On a bien sûr activé le site avec un sudo a2ensite example.com.conf et rechargé apache par un sudo service apache2 restart, conformément au HowTo dédié.
A ce stade, on aboutit au stack suivant, dans la VM :

Et du point de vue de la machine locale, on a le stack suivant :

Dans le dernier schéma, on constate qu'on a tout ce dont on a besoin, il reste juste à relier tout ceci ensemble :
- configurer et tester le plugin remote-sync pour s'assurer que ce dernier fonctionne
- "brancher" le module xdebug de la VM sur notre plugin Atom php-debug ; au moyen d'un tunnel ssh reverse
- configurer le plugin php-debug pour lui fournir un path map correct
On a créé précédemment dans Atom un nouveau dossier de projet, qui se trouve physiquement sur notre machine locale. On avait créé le dossier local ~/project_example.com .
D'autre part, on a défini un nouveau vhost dans le apache de la VM, dont le DocumentRoot a été placé sur la VM à /var/www/example.com. Et le dossier créé avec les bons droits dans la VM, évidemment...
Il s'agit maintenant de régler le plugin atom remote-sync pour qu'il envoie une copie du fichier à chaque modification locale, automatiquement au bon endroit. Ce réglage est fait une fois pour toutes, via un clic droit sur le dossier de projet dans la liste à gauche de la fenêtre d' atom :

On configure le dossier avec les informations qu'on a utilisées tout au long de ces HowTos :
- on envoie les fichiers dans la VM via scp
- le hostname est example.com, la machine locale pense que ce nom de domaine pointe vers l'IP de notre VM grâce à la ligne ajoutée dans le fichier local
/etc/hosts - le port 22 est utilisé par défaut pour scp et ssh
- le target directory est
/var/www/example.com, il s'agit du DocumentRoot du vhost qu'on a créé dans le apache de la VM - le username est simplon, c'est l'utilisateur ssh qui a les droits d'écriture sur les fichiers côté VM
- on utilise un password, qui est simplon comme pour l'user ssh habituel. En fait on utilise précisément cet utilisateur ssh, puisque scp est un outil fourni par ssh. On pourrait utiliser une clé au lieu d'un mot de passe
- on coche la checkbox uploadOnSave, ce qui permettra au plugin de réagir à chaque écriture sur un fichier

On sauve et on teste que cette configuration fonctionne en créant un nouveau fichier index.php à la racine de notre dossier de sources locales :

Ce fichier php contiendrait le code suivant, pour tester :
<?php
$collector = '' ;
foreach($_SERVER as $key=>$value) {
$collector .= $key . ' -> ' . $value . "<br />\n" ;
}
echo $collector ;Lorsqu'on sauve le fichier, on voit un encart en bas de la fenêtre qui résume l'action de la synchro des sources :

On est assurés de conserver des fichiers identiques de part et d'autre : les fichiers édités dans atom seront strictement identiques côté local et dans la VM.
Le module xdebug de la VM envoie déjà des messages de debug, vers l'adresse locale 127.0.0.1, port 9000. Or aucun service n'est à l'écoute dans la VM à cette adresse et sur ce port.
On doit "brancher" cette sortie du module xdebug de la VM à notre plugin atom php-debug en local.
Ce plugin Atom php-debug, lui, écoute déjà lui aussi à l'adresse 127.0.0.1 de la machine locale, sur le port 9000.
On va monter un tunnel ssh reverse, initié depuis la machine locale, et qui permettra une communication depuis le module xdebug de la VM vers notre plugin atom php-debug. C'est cette direction "sortante" du point de vue de la VM qui exige de monter un tunnel reverse.
On monte le tunnel dans un shell de la machine locale :
ssh -N -f -R 9000:127.0.0.1:9000 simplon@example.comNOTE : dans le cas où le retour de cette commande ressemble à
Warning: remote port forwarding failed for listen port 9000, ça signifie qu'un tunnel similaire est déjà monté et occupe déjà le port 9000. Dans ce cas, on peut récupérer le(s) tunnel(s) en question avec un :ps aux|grep 9000 ben 6212 0.0 0.0 44920 708 ? Ss 14:07 0:00 ssh -N -f -R 9000:127.0.0.1:9000 simplon@example.com ben 6302 0.0 0.0 44920 708 ? Ss 14:16 0:00 ssh -N -f -R 9000:127.0.0.1:9000 simplon@example.com ben 6322 0.0 0.0 14264 980 pts/1 S+ 14:18 0:00 grep --color=auto 9000
Qu'on tue avec :
kill 6212 6302Puis on remonte un tunnel tout neuf avec la commande
ssh -Rci-dessus.
On aboutit à ce stade à l'architecture suivante, du point de vue de la machine hôte :

La configuration du plugin php-debug de atom est globale, on doit la modifier pour refléter l'architecture actuelle. On doit renseigner la correspondance entre :
- le chemin des sources dans la VM ; ici le DocumentRoot est sur
/var/www/example/com - le chemin des sources versionnées par git sur le système hôte ; on a créé un dossier de projet à
~/project_example.com
Un exemple de réglage dans les settings du module (voir le paragraphe sur l'installation du plugin) :

Tout est prêt, nous pouvons commencer à 🪲 travailler en pas à pas et à travailler sans 🐛 bugs...
Il suffit maintenant de :
- allumer le debugger dans atom
- placer un breakpoint
- pointer le browser de la machine locale vers notre site http://www.example.com
- contrôler l'éxécution du script, directement dans atom
On clique le bouton en bas à gauche de la fenêtre d'atom pour ouvrir l'encart des outils de debug :
On note la mention Listening on port 9000...
On place un breakpoint sur une des premières lignes de notre script, pour que l'éxécution du script "fasse une pause" à cet endroit, en attendant qu'on agisse avec les outils de contrôle :
On clique à l'endroit où se trouve le point bleu, et ça "allume" en vert le n° de ligne pour représenter le breakpoint.
On utilise son browser préféré sur la machine locale pour accéder au site web qu'on a monté sur example.com.
On pointe donc son browser vers http://www.example.com
La page ne répond pas, et c'est normal : le script est en pause à l'endroit du breakpoint et attend une instruction (continuer, step in, step out, stop, ...).
On voit dans atom que le script est en pause à la ligne de notre breakpoint ; elle a un fond vert foncé :
On peut inspecter les variables dans le cadre Context, par exemple les SuperGlobals.
On peut éxécuter pas à pas le script en cliquant le bouton Step over par exemple, et voir la varialbe $collector se remplir à chaque itération de la boucle :

Le bouton Step over éxécute la ligne en cours et pause à la suivante, alors que le bouton Continue "déroule" le script jusqu'au prochain breakpoint rencontré.

Vous maîtrisez maintenant un environnement professionnel de développement qui présente une foule d'avantages :
- vous travaillez directement sur le nom de domaine final, ça vous fera gagner du temps lors de déploiements de wordpress, par exemple...
- vous ne gérez à la main QUE la copie des sources sur votre machine locale. C'est cette copie qui est versionnée avec git, si la VM flambe c'est pas grave.
- vous développez les nouvelles fonctionnalités hors internet. La VM n'est accessible QUE depuis votre machine locale
- vous développez vos scripts en les testant dans un debugger : vous avez la maîtrise fine des ressources de vos scripts
- on peut imaginer utiliser vagrant (https://www.vagrantup.com/) pour déployer très facilement des environnements similaires
- la liste est longue...
- ...