Php 5 classes de redirection des exceptions dans un système de log

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 752 fois - Téléchargée 18 fois

Contenu du snippet

Voici un système permettant la redirection des exceptions
dans un systeme de log.

1 classe abstraite:
classe logException dérivée de la classe PHP5 Exception

2 classe dérivées
classe logFileException qui redirige l'exception dans un fichier log
classe logDbMysqlException qui redirige l'exception dans une table de base Mysql.
Pour utiliser la source il faut créer une table de log en base comme décrit dans les premières lignes commentées de la source

Source / Exemple :


<?php
/**
Desc:
  Classes gérant la redirection d'exceptions dans un systeme de log
  Pour utiliser le systeme de log dans Mysql
  il faut créer une table logTable dans une base Mysql de votre choix

  CREATE TABLE `TableLog` (
  `id` int(11) NOT NULL auto_increment,
  `time` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `level` varchar(20) NOT NULL default 'WARNING',
  `msg` varchar(300) NOT NULL,
  `line` int(11) NOT NULL,
  `script` varchar(500) NOT NULL,
  `code` int(11) NOT NULL default '1',
  PRIMARY KEY  (`id`)
)

  • /
abstract class logException extends Exception { /** @property :string @desc :heure de lancement de l'exception
  • /
protected $sTime; /** @properties: const string @desc: les niveaux d'erreur
  • /
const LV_WARNING='WARNING'; const LV_NOTICE='NOTICE'; const LV_FATAL='FATAL'; /** @param string $msg : message associé à l'exception @param int $code : code de l'exception @param int $level :niveau d'erreur de l'exception (optionel defaut FATAL)
  • /
public function __construct($msg,$code=1,$level=self::LV_WARNING) { parent::__construct($msg,$code); $this->sTime=date('Y-m-d H:i:s'); $this->logIt($level,$msg); } /** @param int $level :niveau d'erreur de l'exception @param string $msg : message associé à l'exception
  • /
abstract protected function logIt($level,$msg); } /** Desc: Lancement et redirection des exceptions dans un fichier log
  • /
class logFileException extends logException { /** @property :boolean @desc : Flag statique indiquant si le nom du fichier log est horodaté ou non
  • /
protected static $bTimerNamedLog=true; /** @property :string @desc : Nom du fichier log sans l'extension dans lequel va être loguée l'exception
  • /
protected static $logName='logFile'; /** @param string $slogName : Nom du fichier log sans extension @param boolean $bTimerNamedLog : Flag à true si le fichier est horodaté @param string $sLogExt optional defaut (.log) : Extension du fichier @desc : Methode statique définissant les propriétés du fichier log associé. Cette Méthode Peut être appelée sans qu'une exception de ce type soit levée
  • /
public static function setParam($sLogName, $bTimerNamedLog,$sLogExt='.log') { self::$bTimerNamedLog=$bTimerNamedLog; if (self::$bTimerNamedLog===true) self::$logName.=date('Ymd').$sLogExt; else self::$logName.=$sLogExt; } /** @param int $level :niveau d'erreur de l'exception @param string $msg : message associé à l'exception @desc : Traite l'exception dans le fichier log associé
  • /
protected function logIt($level,$msg) { if (file_exists(self::$logName)) $fp=fopen(self::$logName,'a'); else $fp=fopen(self::$logName,'w'); if ($fp) { fputs($fp,strftime('%d/%m/%Y %H:%M:%S', strtotime($this->sTime)).' : '. $level.' - '. $msg.' - Line '. $this->getLine().' in '. $this->getFile()."\n"); fclose($fp); } else die ('Interruption du script: Erreur durant l\'ouverture du '. 'fichier log'); } } /** Desc: Lancement et redirection des exceptions dans une table log en base Mysql
  • /
class logDbMysqlException extends logException { /** @property : object généré par la connexion au serveur de Db @desc : ressource de connexion à la DB Mysql
  • /
protected static $oConnexionRes=NULL; /** @property : array @desc : configuration de la connexion à la base A MODIFIER
  • /
protected static $aConfigParam=array('host'=>'localhost', 'user'=>'root', 'pwd'=>'', 'db'=>'test', 'table'=>'logtable'); /** @desc : Methode statique établissant la connexion si elle n'a pas été effectuée.
  • /
public static function link() { if (self::$oConnexionRes===NULL || !mysql_ping(self::$oConnexionRes)) { $msgdie='Interruption du script dans'. ' la methode '.__CLASS__.'::'.__FUNCTION__. '() sur Probleme de format détecté d\'une clé de config'; if (!array_key_exists('host',self::$aConfigParam)) die ($msgdie); if (!array_key_exists('user',self::$aConfigParam)) die ($msgdie); if (!array_key_exists('pwd',self::$aConfigParam)) die ($msgdie); if (!array_key_exists('table',self::$aConfigParam)) die ($msgdie); self::$oConnexionRes=@mysql_connect(self::$aConfigParam['host'], self::$aConfigParam['user'], self::$aConfigParam['pwd'], true); $db=@mysql_select_db(self::$aConfigParam['db'], self::$oConnexionRes) or die ('Interruption du script dans'. ' la methode '.__CLASS__.'::'.__FUNCTION__. '() :1 ou pluseurs paramètres de connexion sont invalides'); } } /** @param array $aConfig : Paramètres de connexion Exple :array('host'=>'localhost', 'user'=>'root', 'pwd'=>'', 'db'=>'test', 'table'=>'logtable'); @desc : Methode statique initialisant les paramétres de connexion. Les paramètres peuvent être initialisées par cette methode ou directement en modifiant la déclaration de la propriété statique $aConfigParam de la classe
  • /
public static function setParam($aConfig) { if (!is_array($aConfig)) die ('Interruption du script'. ' : '.__CLASS__.'::'.__FUNCTION__.'()'. ' paramètre array attendu'); self::$aConfigParam=$aConfig; self::link(); if (!mysql_ping(self::$oConnexionRes)) { die ('Interruption du script'. ' : '.__CLASS__.'::'.__FUNCTION__.'() un problème '. 'de connexion inconnu a été identifié'); } $queryTest='select 1 from '.self::$aConfigParam['table'].' limit 1'; if (!$result=mysql_query($queryTest,self::$oConnexionRes)) die ('Interruption du script'. ' Erreur dans '.__FUNCTION__.' : La table '. self::$aConfigParam['table'].' est inexistante en base '. self::$aConfigParam['db']); } /** @param int $level :niveau d'erreur de l'exception @param string $msg : message associé à l'exception @desc : Traite l'exception dans le fichier log associé
  • /
protected function logIt($level,$msg) { self::link(); if (self::$oConnexionRes!==NULL) { $res=mysql_query('insert into '.self::$aConfigParam['table']. ' (level,time,msg,line,script,code) values'. '("'.$level.'","'.$this->sTime.'","'. mysql_real_escape_string($msg, self::$oConnexionRes).'",'. $this->getLine(). ',"'.mysql_real_escape_string($this->getFile(), self::$oConnexionRes). '",'.$this->getCode().')',self::$oConnexionRes); if (!$res) die ('<br/>Interruption du script:'. ' Impossible de rediriger la '.__CLASS__. ' en table debase:'. ' erreur rencontrée :'.mysql_error()); } else die ('<br/>Interruption du script sur '.__CLASS__.'::'. __FUNCTION__.'() : '.__CLASS__.'::setParam() doit être '. 'exécutée avant de lancer une '.__CLASS__); } /** @desc : clos la connexion
  • /
public function closeConnexion() { if (mysql_ping(self::$oConnexionRes)) mysql_close(self::$oConnexionRes); } } /** Exemple utilisation des exceptions à rediriger vers un fichier log
  • /
logFileException::setParam('testLog',true); try { throw new logFileException('Exception 1 loguée vers logFile',1, logException::LV_WARNING); } catch(logFileException $e) { echo '<br/>'.$e->getMessage(); try { throw new logFileException('Exception 2 loguée vers logFile',2, logException::LV_NOTICE); } catch(logFileException $e2) { echo '<br/>'.$e2->getMessage(); print_r($e->getTrace()); } } /** 2 eme Exemple : utilisation des exceptions à rediriger vers une db mysql Pour éviter de passer par setParam il faut directement modifier les valeurs dans la déclaration des propriétés de la classe logDbMysqlException
  • /
logDbMysqlException::setParam(array('host'=>'localhost', 'user'=>'userlogin', 'pwd'=>'pwdlogin', 'db'=>'test', 'table'=>'logtable')); try { throw new logDbMysqlException('Exception 1 loguée vers Mysql 1',1, logException::LV_WARNING); } catch(logDbMysqlException $e) { echo '<br/>'.$e->getMessage(); // à Ne pas oublier si derniere exception gérée $e->closeConnexion(); } ?>

A voir également

Ajouter un commentaire

Commentaires

guill76
Messages postés
193
Date d'inscription
mercredi 24 août 2005
Statut
Membre
Dernière intervention
3 juin 2016
-
Salut,
Bon pour le $e->closeConnexion c'est effectivement un truc qui me chagrine aussi.
Si j'intègre le close en fin de logIt ça résoud ce problème mais ça oblige à recréer une connexion à chaque exception et là ça me chagrine encore plus.
Donc je vais essayer de trouver une manière plus souple de procéder.

Pour une utilisation simultanée des 2 types d'exceptions, je n'ai pas coder ce besoin mais pourquoi pas..
"Est-ce vraiment le rôle de l'exception elle-même que de faire un tel traitement?"
Je pense que c'est assez subjectif, mais ta remarque est bonne(je me l'a suis faite aussi=> ta remarque :))
=>Pour moi étant donné qu'on peut avoir 1 évantail de classes d'exception indépendantes les unes des autres à sa disposition on est libre d'utiliser les exceptions qu'on veut et notament celles les + appropriée à ce qu'on veut faire.
Rien ne t'empêches en plus d'utiliser un systeme de log classique en //.
tout ça dépend également aussi de la manière de coder: par exemple si tu gères dans ton code toutes tes erreurs par exceptions là tu peux faire d'une pierre 2 coups (ça t'evites de lancer l'exception classique et à coté de faire du code en plus pour loguer tes erreurs dans un fichier log).
Et là c'était vraiment le but de cette classe dans mon cas.

Voilà et merci pour ta réaction.
cs_FredT
Messages postés
66
Date d'inscription
mardi 18 février 2003
Statut
Membre
Dernière intervention
11 avril 2009
-
Salut
Si... ligne 214: if (!$result=mysql_query($queryTest),self::$oConnexionRes): parenthèse mal placée
Autrement, au niveau de l'idée, ça m'intéresse je suis actuellement sur le même sujet, je risquerai de revenir commenter dans qques jours.

Niveau du code y'a un truc qui me dérange c'est le fait de faire $e->closeConnexion();
dans le bloc catch: pas terrible à cette endroit, l'utilisateur de ta classe va les oublier à coup sûre

Niveau utilisation y manque quelque chose à mon goût, car tu peux soit enregistrer dans DB soit LOG, pas les deux. Pour aller plus loin... admetons que j'étende ta classe abstract avec une logMailException... je pense que tu suis l'idée... même si là le mot "log" commence à plus trop convenir. Mais on reste dans la même voie.

Autre point qui me dérange (je pense peut-etre un peu trop POO, mais si t'as réponse à ça, tu éclairerai ma lanterne.) Est-ce vraiment le rôle de l'exception elle-même que de faire un tel traitement?
Par définition on lance un objet Exception lorsque un bout de code entre dans un cas exceptionnel. Ce cas exceptionnel est testé et attrapé s'il a lieu (try) pour que dans le code utilisateur tu puisse parer à cet évènement (catch) .
guill76
Messages postés
193
Date d'inscription
mercredi 24 août 2005
Statut
Membre
Dernière intervention
3 juin 2016
-
Pas de réactions??

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.