Bien que nous fassions tous du code diamant (magnifique, solide et transparent), ce dernier vit sa vie et les problèmes surgissent. Voici le “meilleur” d’entre eux :

La page blanche
La page blanche

Lors du SymfonyLive 2015, Nicolas Grekas a présenté ce que le framework Symfony vous apporte pour déboguer confortablement. Il est le CTO de Blackfire et participe, avec la communauté, au développement des composants Debug et VarDumper.

Les outils existants

Tout d’abord, faisons un petit tour d’horizon de ce que nous avons déjà à disposition avant de zoomer sur la conférence de Nicolas Grekas.

Attention : dans ce chapitre, les points abordés sont à l’attention des développeurs dans leur environnement de développement. Réfléchissez bien avant d’utiliser ces éléments en production. Ils peuvent fournir des informations que vous préféreriez garder pour vous, dégrader l’expérience utilisateur, etc…

Die

Le réflexe primal :

<?php
die('toto');

On traque le problème par dichotomie. On place la commande dans le début du script puis on l’éxecute à nouveau. Si “toto” s’affiche, on déplace la commande jusqu’à ce que “toto” ne s’affiche plus. La ligne précédente est donc celle qui provoque le problème. Vous n’obtenez aucune information sur le problème réel, uniquement “quand” il intervient.

Oubliez ça...
Vous oubliez cette méthode, vous êtes un développeur avec de l’amour propre et peu de temps alloué au débogage

PHP

Pour commencer, PHP renseigne un fichier de log dans lequel vous retrouverez les erreurs et leurs messages.

Sinon pour améliorer les choses, un peu de configuration peut faire des miracles. Dans le fichier php.ini, vous pouvez changer la valeur de error_reporting pour le niveau d’erreur E_ALL qui provoquera l’affichage de tous les types d’erreurs. A vous de trouver le bon niveau d’erreur pour vos besoins. Vous pouvez également mettre display_errors à 1, vos erreurs seront directement affichées sur la sortie standard. A savoir, le paramètre de configuration html_errors permet d’enrichir ces erreurs en HTML par du style appliqué et des liens vers la documentation PHP.

Ces points vous permettront de mieux comprendre le contexte de l’erreur.

Xdebug

C’est le nom d’une extension PHP dédiée à la compréhension de ce que le script a effectué : ses deux principales fonctions sont le débogage et le profilage.

Pour obtenir l’extension sous Debian & cie :

sudo apt-get php5-xdebug

Une fois installée, l’extension traque les appels aux fonctions, leurs valeurs des différents arguments et de nombreuses métriques liées à l’utilisation mémoire, CPU, I/O… Cette collecte permet justement d’enrichir certaines outils de débogage fournis avec PHP. Ainsi, si vous utilisez la fonction var_dump(), de nouvelles informations vont être ajoutées. Par exemple, lors d’une exception non interceptée, en plus du type et du message, la pile des appels sera affichée avec la quantité de mémoire, les méthodes et leur localisation.

Sans Xdebug
Avec Xdebug
Voici le rendu de var_dump par défaut VS avec Xdebug
Sans Xdebug
Avec Xdebug
Voici le rendu des exceptions par défaut VS avec Xdebug

Débogage pas à pas

L’extension Xdebug donne également accès au débogage pas à pas. Si votre IDE le supporte, vous pouvez étudier en temps réel l’exécution de votre script.

Pour l’activer, ajoutez au fichier xdebug.ini (ou a votre fichier php.ini en fonction de votre installation) :

xdebug.remote_enable=1
xdebug.remote_port="<the port for xdebug to listen to>" (the default port is 9000)
xdebug.profiler_enable=1
xdebug.profiler_output_dir="<path to tmp>"

Votre IDE doit également être configuré pour se connecter au port du serveur qui exécutera le script. Il ne vous restera plus qu’à lancer une session de débogage.

Le principe est de placer un point d’arrêt dans votre code. Ensuite, à l’exécution de votre script PHP, le processus sera mis en attente quand le point d’arrêt sera atteint. Votre IDE vous indiquera le fichier et la ligne atteinte et vous montrera les variables et leur contenu. Vous aurez le choix de laisser le script continuer son fonctionnement normal ou exécuter les commandes une à une. Ainsi vous aurez une excellente compréhension de la situation situation car tout le contexte en cours est accessible par votre IDE : vous pouvez demander les valeurs des variables…

Pas à pas
Débogage pas à pas avec PHPStorm

Toutefois, la procédure peut être difficile et longue à mettre en place, donc exagérée pour une majorité de bugs.

Les fonctionnalités liées au débogage de Symfony

Lors du SymfonyLive 2015, Nicolas Grekas a pris la parole pour indiquer comment Symfony nous aide au débogage tous les jours, confortablement. Il nous a parlé des deux composants dédiés aux erreurs et à la correction des bugs.

Debug

Tout d’abord, il faut pouvoir accéder aux informations. PHP dispose de plusieurs fonctions qui seront exécutées au moment où les problèmes surviennent. Vous pouvez aussi surcharger ou remplacer les méthodes qui effectueront certains traitements, comme le chargement automatique des classes par exemple.

Pour lancer le composant, une commande suffit Debug::enable(); Vous pouvez également demander à votre application Symfony, via son kernel, que vous cherchez à déboguer en mettant l’argument debug de AppKernel à true.

Vous avez un exemple dans le fichier web/app_dev.php d’un projet PHP :

<?php

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Debug\Debug;

// ...

$loader = require_once __DIR__.'/../app/bootstrap.php.cache';
Debug::enable();

require_once __DIR__.'/../app/AppKernel.php';

$kernel = new AppKernel('dev', true);
// ...

Le composant agit sur les fonctions natives suivantes :

A savoir, ce composant va bien plus loin que le formattage HTML et la trace des appels proposés par XDebug. Le composant améliore la lisibilité du rapport d’erreurs, notament avec une mise en avant des éléments importants.

Mais aussi avec l’ajout de prédictions. Cela se traduit par une aide apportée en analysant l’erreur pour faciliter la correction. Ainsi si un fichier est inclus et qu’aucune classe correspondant au nom du fichier est trouvée, il s’agit souvent d’une typo, c’est donc ce qui vous sera suggéré.

Typo
Typo dans le nom d’une classe

Mais ça va plus loin. Afin que vous ne ratiez aucun problème, les erreurs sont interceptées, un niveau leur est associé puis elles sont enregistrées.

Si vous voulez voir comment agit le composant, rendez-vous dans les méthodes suivantes :

  • ErrorHandler::register()
  • ExceptionHandler::register()
  • DebugClassLoader::enable()

Ces dispositions vous aident déjà beaucoup au quotidien, avec un minimum de configuration à faire. Le composant n’est pas activé en production, toutefois si vous effectuez votre propre configuration, il peut vous aider.

VarDumper

Nicolas Grekas a poursuivit par la présentation de VarDumper, dont il est l’initiateur. Le but du composer est d’aider dans l’analyse du contenu des variables. Dans un framework tel que Symfony, les objets contiennent souvent des références vers d’autres objets. Ainsi, il peut rapidement exister des références circulaires ou une grande quantité de données a afficher.

C’est dans cette optique que la méthode dump() est apparue. Comme var_dump(), le contenu des variables sera affiché, mais en allant plus loin, en mentionnant les références par exemple. Elle existe dans Twig également.

dump
Formattage HTML de dump()

Les traces des appels à la fonction dump() peuvent être invisibles, mais elles seront toujours affichées dans la barre de débogage de Symfony.

Les trucs et astuces de Nicolas Grekas

Backport

Si le composant est natif à partir de Symfony 2.6, pas de panique pour ceux qui sont dans les versions précédentes (qui sont restés en 2.3 pour la LTS par exemple). En effet, il existe un backport.

Pour le mettre sur votre projet :

composer require --dev tchwork/debug-bundle

Puis suivre les instructions du readme.

Installation globale

Le composant VarDumper n’est pas réservé à Symfony ! Vous pouvez l’installer au niveau de votre php.ini grâce au “prepend”. Ainsi vous pourrez l’utiliser à votre guise dans tous vos scripts.

composer global require symfony/var-dumper

Dans votre php.ini :

auto_prepend_file=/path/to/.composer/vendor/autoload.php

Localisation du code dans la pile des appels

Pour avoir des liens sur les références du code, dans la pile des appels, qui donnent directement dans votre IDE préféré, vous pouvez définir ceci dans votre php.ini :

# SublimeText
xdebug.file_link_format=subl://%f:%l

# PHPStorm (dépend de votre OS et de la version de PHPStorm)
xdebug.file_link_format=pstorm://%f:%l
xdebug.file_link_format=phpstorm://?file=%f:%l 

Pour aller plus loin

Au delà du débogage, vous allez vouloir profiler votre script, c’est-à-dire voir les fonctions qui ont été appelées, dans quel ordre et quelle est la durée consommée par les fonctions. Pour ceci, Blackfire vous permettra d’effectuer une analyse de l’exécution du script, vous fournira des métriques et vous conseillera dans ce qui est pertinent.

profil Blackfire
Un profil dans Blackfire

Pour ceux qui utilisent Firefox et Firebug, il existe une extension Firebug qui vous permet de remonter des logs PHP directement dans votre navigateur.

Vous voilà armé, bonne chasse aux bugs !