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

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

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.