1: <?php
2: // declare(encoding='UTF-8');
3: /**
4: * Classe de gestion des exceptions.
5: * C'est un Singleton.
6: *
7: * @category PHP 5.2
8: * @package Framework
9: * @author Aurélien PERONNET <aurelien@tela-botanica.org>
10: * @author Jean-Pascal MILCENT <jmp@tela-botanica.org>
11: * @copyright Copyright (c) 2009, Tela Botanica (accueil@tela-botanica.org)
12: * @license GNU-GPL-v3 <http://www.gnu.org/licenses/gpl.html>
13: * @license CECILL-v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt>
14: */
15: class GestionnaireException {
16:
17: const MODE_CLI = 'cli';
18:
19: /** Liste des exceptions enregistrées */
20: private static $exceptions = array();
21:
22: /** Détermine si l'on affiche ou non le contexte */
23: private static $contexte = false;
24:
25: /** Détermine si l'on loggue ou non les erreurs */
26: private static $logger = false;
27:
28: /** Détermine si l'affichage des erreurs est forcé (true) ou pas (false) à la destruction de la classe */
29: private static $afficher = false;
30:
31: /** Definit si php est lancé en ligne de commande ou en mode serveur */
32: private static $mode = null ;
33:
34: /** Initialise le Gestionnaire d'exceptions et d'erreur sans tenir comptes des paramêtres de config. */
35: public static function initialiser() {
36: self::$mode = php_sapi_name();
37: // Désactivation des balises HTML dans les messages d'erreur de PHP en mode ligne de commande
38: if (self::$mode == self::MODE_CLI) {
39: ini_set('html_errors', 0);
40: }
41:
42: set_exception_handler(array(get_class(),'gererException'));
43: set_error_handler(array(get_class(),'gererErreur'));
44: }
45:
46: /** Configure le Gestionnaire d'exceptions et d'erreur à partir des paramêtres de config. */
47: public static function configurer() {
48: self::$contexte = Config::get('fw_debogage_contexte');
49: self::$logger = Config::get('fw_log_debogage');
50: self::$afficher = Config::get('fw_debogage');
51: }
52:
53: /** Renvoie le booleen définissant si l'on affiche le contexte ou non */
54: public static function getContexte() {
55: return self::$contexte;
56: }
57:
58: /**
59: * Definit si l'on veut afficher le contexte ou non
60: * @param bool true si on veut afficher le contexte, false sinon, par défaut vaut false
61: */
62: public static function setContexte($contexte) {
63: self::$contexte = $contexte;
64: }
65:
66: /**
67: * Fonction de gestion des exceptions, remplace le handler par défaut
68: * @param Exception $e l'exception à traiter
69: */
70: public static function gererException(Exception $e) {
71: // pour le moment on se contente de l'ajouter au tableau et de les afficher
72: self::$exceptions[] = $e;
73: // Log si nécéssaire
74: self::loggerException($e);
75: }
76:
77: /**
78: * Gère les erreurs en les convertissant en exceptions (remplace la fonction gestion d'erreurs native de php)
79: * @param int $niveau le niveau de l'erreur
80: * @param string $message le message associé à l'erreur
81: * @param string $fichier le nom du fichier où l'erreur s'est produite
82: * @param int $ligne la ligne où l'erreur s'est produite
83: * @param string $contexte le contexte associé à l'erreur
84: */
85: public static function gererErreur($niveau, $message, $fichier, $ligne, $contexte){
86: // Si un rapport d'erreur existe, création d'une exception
87: if (error_reporting() != 0) {
88: $e = new ErrorException($message, 0, $niveau, $fichier, $ligne);
89: // que l'on donne au tableau d'exceptions
90: self::$exceptions[] = $e;
91: // Log si nécéssaire
92: self::loggerException($e);
93: }
94: return null;
95: }
96:
97: /**
98: * Renvoie les exceptions au format (X)HTML
99: * ou bien au format texte suivant le mode d'utilisation de PHP
100: */
101: public static function getExceptions() {
102: $retour = '';
103: foreach (self::$exceptions as $cle => $e) {
104: switch (self::$mode) {
105: case self::MODE_CLI :
106: $retour .= $e->getMessage()."\n";
107: $retour .= 'Fichier : '.$e->getFile()."\n";
108: $retour .= 'Ligne : '.$e->getLine()."\n";
109: if (self::getContexte()) {
110: $retour .= 'Contexte : '."\n".print_r($e->getTraceAsString(), true)."\n";
111: }
112: break;
113: default:
114: $retour .= '<div class="debogage">'."\n";
115: $retour .= $e->getMessage()."\n";
116: $retour .= '<span class="debogage_fichier">'.'Fichier : '.$e->getFile().'</span>'."\n";
117: $retour .= '<span class="debogage_ligne">'.'Ligne : '.$e->getLine().'</span>'."\n";
118: if (self::getContexte()) {
119: $retour .= '<pre>'."\n";
120: $retour .= '<strong>Contexte : </strong>'."\n".print_r($e->getTraceAsString(), true)."\n";
121: $retour .= '</pre>'."\n";
122: }
123: $retour .= '</div>'."\n";
124: }
125: // Nous vidons le tableau des exceptions au fur et à mesure
126: unset(self::$exceptions[$cle]);
127: }
128: return $retour;
129: }
130:
131: /**
132: * Logue une exception donnée sous une forme lisible si self::logger vaut true.
133: * @param Exception $e l'exception à logger
134: */
135: private static function loggerException($e) {
136: if (self::$logger) {
137: $erreur = '';
138: $erreur .= $e->getMessage()."\n";
139: $erreur .= 'Fichier : '.$e->getFile()."\n";
140: $erreur .= 'Ligne : '.$e->getLine()."\n";
141: if (self::getContexte()) {
142: $erreur .= 'Contexte : '."\n".print_r($e->getTraceAsString(), true)."\n";
143: }
144: $erreur .= "\n";
145: Log::ajouterEntree('erreurs', $erreur);
146: }
147: }
148:
149: public function __destruct() {
150: // Si des erreurs n'ont pas été affichée nous forçons leur affichage
151: if (self::$afficher && count(self::$exceptions) > 0) {
152: echo self::getExceptions();
153: }
154: }
155:
156: }
157: ?>