Gestion personnalisée
des erreurs PHP

Dans la série « présentation de WdCore », je vous propose aujourd'hui la découverte de la classe WdDebug qui m'est bien utile pour trouver rapidement d'où viennent les problèmes ou – lorsque la phase de production est terminée – d'être prévenu d'éventuelles erreurs avant que cela ne puisse être gênant pour le client ou un de ses visiteurs.

En savoir plus sur WdCore.
Télécharger la dernière version de WdCore.

Présentation

La classe WdDebug définit un ensemble de fonctions et de méthodes permettant de personnaliser et d'étendre le système d'erreurs de PHP5. Elle propose :

  • Un système non intrusif de journalisation de messages.
  • Des fonctions de traitement de la pile d'appel PHP.
  • Une gestion personnalisée des erreurs.
  • Un système de rapport d'erreur.

Afin de nous concentrer sur la gestion personnalisée des erreurs, le système de journalisation de messages ne sera pas développé dans ce billet. Il fera, je l'espère bientôt, l'objet d'un billet distinct.

Commençons donc par le commencement : La personnalisation de la gestion des erreurs de PHP.

Personnaliser la gestion des erreurs

Ce n'est pas très difficile de mettre en place sa propre gestion des erreurs PHP, il suffit tout simplement d'utiliser la fonction set_error_handler() avec pour paramètre la fonction callback qui gérera l'erreur. La classe WdDebug met à notre disposition une telle fonction, le code suivant nous permettra de l'utiliser :

<?php

set_error_handler(array('WdDebug''errorHandler');

Un premier test

Voyons ce que cela donne avec le code fautif suivant :

<?php

$a = $b// où $b n'est pas défini

Par défaut :

Notice: Undefined variable: b in G:\Weirdog\www\wd\wdpublisher\packages\user\modules\users\module.php on line 18

Avec notre gestion personnalisée :

Error with the following message:

Undefined variable: b

in G:\Weirdog\www\wd\wdpublisher\packages\user\modules\users\module.php at line 18

Stack trace:

#00 — (0): mysql_fetch_object(Resource of type..., User)
#01 — G:/Weirdog/www/wd/wdcore/wdsql.php(220): call_user_func_array(mysql_fetch_obje..., Array)
#02 — G:/Weirdog/www/wd/wdpublisher/packages/user/modules/users/module.php(109): WdSQL->fetch(Resource of type..., 4, User)
#03 — G:/Weirdog/www/wd/wdcore/wddatabasetable.php(300): user_users_WdModule->fetchEntry(Resource of type...)
#04 — G:/Weirdog/www/wd/wdpublisher/packages/user/modules/users/module.php(154): WdDatabaseTable->load(1)
#05 — G:/Weirdog/www/wd/wdcore/wdcore.php(542): user_users_WdModule->startup()
#06 — G:/Weirdog/www/wd/wdcore/wdcore.php(711): WdCore->getModule(user.users)
#07 — G:/Weirdog/www/wd/wdpublisher/includes/wdpcore.php(150): WdCore->runModules()
#08 — G:/Weirdog/www/wd/wdcore/wdcore.php(654): WdPCore->runModules()
#09 — G:/Weirdog/www/wd/wdpublisher/includes/wdpcore.php(107): WdCore->run()
#10 — G:/Weirdog/www/wd/wdpublisher/includes/startup.php(13): WdPCore->run()
#11 — G:/Weirdog/www/wd/wdpublisher/publisher.php(14): require(G:\Weirdog\www\w...)
#12 — /debug.php(3): require_once(G:\Weirdog\www\w...)

Bon, ça va pas révolutionner le genre, mais on a enfin le parcours de notre code avant qu'il ne tombe sur un OS, ce qui est tout de même bien pratique.

Bien sûr on ne va pas s'arrêter là. Afficher les erreurs c'est bien, mais parfois c'est aussi utile d'en déclencher.

Déclencher une erreur

Déclencher une erreur peut s'avérer utile pour générer un message particulier lors de l'exécution. Par exemple signaler l'utilisation d'une méthode dépréciée, ou l'utilisation d'un identifiant erroné. Il s'agit de déclencher des erreurs gentilles, pour les erreurs fatales on ira plutôt voir du côté des exceptions, comme celles générées par la classe WdException que nous verrons dans un prochain billet.

Pour déclencher une erreur on peut utiliser la fonction standard trigger_error() ou bien la méthode WdDebug::trigger(). L'avantage de la méthode est de proposer les fonctions de localisation de la classe WdLocale ainsi qu'un entête différent permettant de mieux discerne le message. Voyons cela avec le morceau de code suivant :

<?php

class WdForm
{
    ...
    public function __construct(array $tags$container_type='table', array $container_tags=array())
    {
        ...
                case self::T_MANDATORIES:
                {
                    WdDebug::trigger('T_MANDATORIES is obsolete: \1'$value);
                }
                break;
    }
    ...
}

...

$form = new WdForm
(
    array
    (
        WdForm::T_MANDATORIES => array
        (
            'username''password'
        )
    )
);

Et voilà le message d'erreur généré par la méthode WdDebug::trigger().

Backtrace with the following message:

T_MANDATORIES is obsolete:

Array
(
    [0] => username
    [1] => password
)

in G:\Weirdog\www\wd\wdelements\wdform.php at line 128

Stack trace:

#00 — /debug.php(26): WdForm->__construct(Array)

Rapports d'incidents

On a beau être des dieux du développement web, il est possible que des problèmes apparaissent une fois notre code si beau et si parfait livré en pâture à notre pire cauchemar : l'utilisateur.

Alors on peut attendre sagement de recevoir un email de notre client signalant qu'une page affiche un étrange message d'erreur ou pire ne marche pas, mais on préfèrera sans doute recevoir une alerte automatique avant que cela ne gène qui que ce soit.

WdDebug propose de prévenir plutôt que de guérir, en envoyant sur votre boite email les erreurs qui se produisent sur le site, quelles soient générées par PHP ou par la méthode WdDebug::trigger(). Pour cela la classe met à votre disposition deux constantes : WDDEBUG_SILENT et WDDEBUG_REPORT_ADDRESS.

Des erreurs silencieuses

La constante WDDEBUG_SILENT vous permet de choisir la verbosité des messages d'erreur. Par défaut les messages d'erreur sont affichés dans le flot de la page. Définissez cette constante à true pour que les erreurs disparaissent dans le silence.

<?php

define('WDDEBUG_SILENT'true);

require_once 'wddebug.php';

Des erreurs qui écrivent

Si vous souhaitez recevoir sur votre boite email les erreurs qui se produisent sur le site de votre client, il vous suffit de spécifier votre adresse email en utilisant la constante WDDEBUG_REPORT_ADDRESS :

<?php

define('WDDEBUG_REPORT_ADDRESS''myname@myhost.com');

require_once 'wddebug.php';

Imaginons maintenant que nous sommes sur le site de notre client (www.google.com) et que nous avons écrit le code suivant :

<?php

$a = $b// où $b n'est pas défini

Nous recevrons alors un email intitulé « WdDebug: Report from google.com » ayant pour adresse d'envoie « wddebug@google.com » et pour corps :

Error with the following message:

Undefined variable: b

in /home/1232/www/index.php at line 23

De quoi réagir au plus vite pour fixer tout ça.

Pour résumer

On définit les constantes selon nos besoins, on inclut la classe WdDebug à notre code et on personnalise la gestion des erreurs en utilisant la fonction errorHandler() de la classe :

<?php

define('WDDEBUG_SILENT'true);
define('WDDEBUG_REPORT_ADDRESS''me@mycompany.com')

require_once 'wddebug.php';

set_error_handler(array('WdDebug''errorHandler');

C'est pas plus compliqué ! Et ça facilite drôlement la vie, surtout si comme moi vous reprenez le développement moisi laissé par d'anciens collègues peu scrupuleux :-)

Laisser un commentaire

2 commentaires

Peach
Peach

Bonjour,

Je cherche à mettre en place une gestion des erreurs dans mes programmes php. A lecture de votre article, la solution WdDebug m'a parue parfaitement adaptée à mes attentes. J'ai donc téléchargé la dernière version de WdCore. Or, au premier include du fichier 'wddebug.php', une série d'erreurs se déclenchent en cascade (dès que j'en corrige une une autre est générée à un autre endroit) :

Parse error: parse error, unexpected T_ARRAY, expecting '&' or T_VARIABLE in /wdcore/wdlocale.php on line 112 Parse error: parse error, unexpected T_ARRAY, expecting '&' or T_VARIABLE in /wdcore/wddebug.php on line 302

Savez-vous à quoi cela est-il du ? Je souhaiterai implémenter une gestion des erreurs avec WdDebug mais avec ces problèmes le framework est rendu inutilisable.

Par avance, merci. Peach

Olivier
Olivier

Salut Peach,

Dis-moi, quelle version de PHP utilises-tu ?

Il te faut au moins la version 5.2 pour utiliser le framework. L'erreur à la quelle tu fais référence se produit à cause de l'utilisation du typage des paramètres. Cette fonctionnalité a été introduite par la version 5.1 de PHP.