Inscription -

Informations

Cree le 01/01/2010

Modifie le 04/02/2010

PHP

# Elfangels

#####

Actions

Participants

Pas de participants

Associations

Pas de dossiers associes

Partager

Share |

Traitement des erreurs et des exceptions

Développer son site web, c'est bien mais une fois en ligne, c'est mieux d'en suivre l'activité et notamment quand ca se passe mal. C'est pourquoi différents outils de traitement d'erreurs et d'exceptions ont vu le jour. En PHP nous pouvons demander à traiter nous même les erreurs et les exceptions à travers des callbacks (fonctions de rappel). En anglais, on appelle ça du handling (prise en main), vous trouverez d'avantages d'information avec ce terme. Partant du fait qu'on peut traiter les erreurs et les exceptions, il serait bon de pouvoir les enregistrer de manière à pouvoir localiser et corriger au mieux les bugs.

Traiter

Les callbacks

Avant de pouvoir demander traiter nous même les erreurs et les exceptions, il nous faut savoir ce qu'est un callback. Si vous savez déjà de quoi il s'agit, les créer et les manipuler, passez au chapitre suivant. Comme je le disais précédemment, les callbacks sont des fonctions de rappel. Ils pointent sur une fonction ou une méthode et sont manipulables comme une fonction classique. Exemple de création et de manipulation de callbacks :

// Definition de fonction
function maFonction($param) {
   echo 'maFonction('.$param.')';
}

// Definition de classe
class MaClasse {
   public function maMethode($param) {
      echo 'MaClasse->maMethode('.$param.')';
   }

   public static function maMethodeStatique($param) {
      echo 'MaClasse::maMethodeStatique('.$param.')';
   }
}

// Creation d'un objet MaClasse
$objet = new MaClasse();

// Creation des callbacks
$fonction = 'maFonction';
$methode = array($objet,'maMethode');
$methodeStatique = array('MaClasse','maMethodeStatique');

// Appels
call_user_func($fonction,'hello');
call_user_func($methode,'hello');
call_user_func($methodeStatique,'hello');
Ce code produira à l'exécution :

maFonction(hello)
MaClasse->maMethode(hello)
MaClasse::maMethodeStatique(hello)


L'intérêt des callbacks est de pouvoir donner en paramètre un traitement. Exemple : pour généraliser "multiplier par 2 toutes les cellules d'un tableau", nous pouvons créer une fonction qui effectue un traitement sur un tableau à laquelle on passe un callback qui sera appelée par la fonction pour chaque cellule du tableau (à vrai dire, cette fonction existe déjà et s'appelle array_map).

// Fonction qui retourne le double de la valeur passee en parametre
function double($val) {
	return $val*2;
}

// Callback qui pointe sur la fonction double
$monCallback = 'double';

// Creation du tableau
$monTableau = array(2,4,6);

// On applique la fonction double sur tous les elements sur tableau
$monNouveauTableau = array_map($monCallback,$monTableau);

// On affiche le nouveau tableau
print_r($monNouveauTableau);
Résultat de l'exécution de ce script :

Array ( [0] => 4 [1] => 8 [2] => 12 )


Toutes les valeurs du tableaux ont bien été multipliées par 2.

Pour plus d'information sur les callbacks, rendez vous sur la page Variables et pseudo-types utilisés dans cette documentation du site officiel PHP.

Handling

Nous l'avons vu précédemment, handling signifie prise en main. Il s'agit pour nous de prendre en main le traitement des erreurs et des exceptions. Pour cela en PHP, nous avons deux fonctions qui permettent de définir un callback qui sera appelé lorsqu'une erreur ou une exception survient : set_error_handler() et set_exception_handler().

Erreurs

// Fonction de traitement d'erreurs personnalise
function traitementErreurs($err_no, $err_str, $err_file, $err_line) {
   echo 'Error '.$err_no.' in '.$err_file.' at line '.$err_line.', '.$err_str;
}

// Callback vers notre fonction
$callback = 'traitementErreurs';

// Definir notre fonction comme handler d'erreurs
set_error_handler($callback);

// Declencher une erreur
echo $variableNonDefinie;
Ce script donnera à l'exécution :

Error 8 in D:\Sites Web\Zend Studio\MyHomework\index.php at line 15, Undefined variable: variableNonDefinie


Exceptions

// Fonction de traitement d'exceptions personnalise
function traitementExceptions($e) {
   echo 'Exception '.$e->getCode().' in '.$e->getFile().' at line '.$e->getLine().', '.$e->getMessage();
}

// Callback vers notre fonction
$callback = 'traitementExceptions';

// Definir notre fonction comme handler d'erreurs
set_exception_handler($callback);

// Soulever une exception
throw new Exception('Usage incorrect !');
A l'exécution, ce script donnera :

Exception 0 in D:\Sites Web\Zend Studio\MyHomework\index.php at line 15, Usage incorrect !


Pour plus d'information sur la gestion des erreurs, rendez vous sur la page Gestion des erreurs et des journaux du site officiel PHP.

Enregistrer

Présentation de la classe Log

Nous avons vu comment traiter nous même les erreurs et les exceptions, il nous faut un moyen de garder une trace et de préférence exploitable. Pour vous faciliter le travail, voici une classe de gestion des logs que j'ai conçu et qui présente deux points intéressants : elle permet de faire du traitement d'erreurs et d'exceptions, elle permet également de laisser au développeur le choix d'implémentation de l'enregistrement des logs (fichier XML, base de données, ...). Pour ceux qui connaissent, il s'agit de la mise en oeuvre du patron de conception Stratégie. Inutile de afficher ici tout le code, télécharger le zip suivant :



Vous devez y trouvez deux fichier : log.php (contient la classe Log et l'interface ILogData) et log_data.php (qui contient les classes LogData_File et LogData_File_XML). En plus du code qui est suffisamment documenté, voici un petit diagramme des classes pour clarifier ces différentes classes et interface :


 Afficher l'image


Pour faire simple, la classe Log s'occupe de la gestion des logs et utilise un objet qui respecte l'interface ILogData pour les enregistrer. Deux classes d'enregistrement de logs sont déjà données : LogData_File et LogData_File_XML. Mais vous pouvez en développer d'autres, il suffit d'implémenter l'interface ILogData qui impose de proposer la méthode add prenant en paramètre la catégorie du log et un tableau associatif contenant les données du log. Attention tout de même à ne pas faire d'erreurs dans vos "LogData" car sinon ca risque de boucler (une erreur arrive, tentative d'enregistrement, erreur lors de l'enregistrement, ...).

Utilisation de la classe Log

Lisez un peu les entêtes des différentes méthodes et vous devriez comprendre la mécanique de la chose. Voici quand même un exemple d'utilisation qui génère des documents XML :

// Creer l'objet log
$log_data = new LogData_File_XML('./logs/');
$log = new Log($log_data);

// Definir l'objet log comme gestionnaire d'erreurs et d'exceptions 
set_error_handler(array($log,'addError'));
set_exception_handler(array($log,'addException'));
Simple d'utilisation, n'est ce pas ? Vous pouvez définir une page où sera redirigé le visiteur lorsqu'une erreur ou une exception arrive :

// Fonction qui redirige le visiteur
function redirect($page) {
   die('<script type="text/javascript">window.location = \''.$page.'\';</script><a href="'.$page.'">Pour continuer, cliquez ici.</a>');
}

// Callback qui pointe sur la fonction redirect
$callback = 'redirect';

// Specifier les pages ou sera redirige le visiteur lorsequ'une erreur/exception survient
$log->addErrorsPage('error.php',$callback);
$log->setExceptionsPage('exception.php',$callback);
De plus, sachez que la classe Log vous permet d'avoir plusieurs "LogData", il suffit d'appeler la méthode addLogData. Dernier point, votre objet log permet non seulement de gérer les erreurs/exceptions mais vous permet également d'enregistrer vos propres messages avec la méthode addMessage, exemple :

$log->addMessage('Administration','Tous les parametres ont ete reinitialises');
Certains paramétrages sont possibles, notamment au niveau des types d'erreurs, rendez vous à la documentation à chaque entête de méthode.

Présenter

Nous y voila pour la dernière partie de notre tutorial, nous savons comment traiter et enregistrer les erreurs et les exceptions, il nous faut maintenant les exploiter. Tout d'abord, sachez que PHP met à disposition les classes nécessaires pour manipuler un document XML, plus d'informations par ici, libre à vous de développer un outil qui analyse et met en forme les logs XML. Nous allons voir ici comment mettre en forme le XML via une feuille de style XSL.

Attention, cette partie ne veut en aucun cas remplacer un tutorial complet sur le XSL.

Le principe

Les bons développeurs le savent, les données et le style sont deux choses bien différentes et doivent être séparées, pour différentes raisons telles que la portabilité et la facilité de maintenance. C'est par exemple sur quoi repose le CSS, nous avons des pages HTML d'un côté et une (voir plusieurs) feuille de style CSS. Ici, c'est exactement le même principe : nous avons d'un côté nos documents XML et de l'autre notre feuille de style XSL. Voici un petit schéma qui nous explique la transformation d'un document XML en document HTML (il est également possible de transformer un document XML en document PDF, XML, ...) :


 Afficher l'image


Dans votre feuille de style XSL, vous définissez des templates (modèles en français) pour les éléments du dom XML. Dans notre cas, on doit définir comment s'affiche une erreur, une exception et un message. Il y a un template principal qui défini comment se présente le document dans son ensemble. Les différents templates peuvent s'appeler les uns les autres, par exemple, le template principal doit lister toutes les erreurs/exceptions/messages ce qui a pour effet d'appeler leur template respectif. Voici un exemple pour mieux expliquer mes dires :

<?xml version="1.0" encoding='iso-8859-1'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl : output method="html" />

   <!-- Template principal -->
   <xsl:template match="/">
      <table>
         <thead>
            <tr>
               <th>Date</th>
               <th>Code</th>
               <th>Message</th>
               <th>File</th>
               <th>Line</th>
               <th>URL</th>
               <th>IP</th>
            </tr>
         </thead>
         <tbody>
            <xsl:apply-templates select="/logs/errors/error" />
         </tbody>
      </table>
   </xsl:template>

   <!--Template d'une erreur -->
   <xsl:template match="error">
      <tr>
         <td><xsl:value-of select="@date" /></td>
         <td><xsl:value-of select="@code" /></td>
         <td><xsl:value-of select="@message" /></td>
         <td><xsl:value-of select="@file" /></td>
         <td><xsl:value-of select="@line" /></td>
         <td><xsl:value-of select="@url" /></td>
         <td><xsl:value-of select="@ip" /></td>
      </tr>
	</xsl:template>
</xsl:stylesheet>
Pour plus d'informations sur les feuilles de style XSL, rendez vous sur le site du W3C

La feuille de style

Histoire de vous faciliter le travail, voici la feuille de style déjà toute faite :



Cette feuille de style requiert jquery, jquery.tablesorter et jquery.tablesorter.pager ainsi la collection d'icônes fugue.

Pour attacher cette feuille de style, il faut utiliser la méthode setStyleSheet de la classe LogData_File_XML :

$log_data->setStyleSheet('logs.xsl');
Voici un aperçu de ce que cela peut donner :


 Afficher l'image


Fin

J'espère que ce tutorial vous aura bien appris les techniques expliquées sur le traitement des erreurs et des exceptions. Si vous avez des questions, n'hésitez pas à m'envoyer un message via le forum ou mon profil.

Commentaires





Pas encore de commentaires
Webmaster Up - Portfolio - Credits - 2005/../2009
NeoTech Center
ContestOrg Homea NeoCover Perrin's Team Webmaster Up WebProjectHelper