Subversion Repositories Applications.framework

Rev

Rev 369 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 369 Rev 497
1
<?php
1
<?php
2
// declare(encoding='UTF-8');
2
// declare(encoding='UTF-8');
3
/**
3
/**
4
 * Classe de gestion des exceptions.
4
 * Classe de gestion des exceptions.
5
 * C'est un Singleton.
5
 * C'est un Singleton.
6
 *
6
 *
7
 * @category	PHP 5.2
7
 * @category	PHP 5.2
8
 * @package	Framework
8
 * @package	Framework
9
 * @author		Aurélien PERONNET <aurelien@tela-botanica.org>
9
 * @author		Aurélien PERONNET <aurelien@tela-botanica.org>
10
 * @author		Jean-Pascal MILCENT <jmp@tela-botanica.org>
10
 * @author		Jean-Pascal MILCENT <jmp@tela-botanica.org>
11
 * @copyright	Copyright (c) 2009, Tela Botanica (accueil@tela-botanica.org)
11
 * @copyright	Copyright (c) 2009, Tela Botanica (accueil@tela-botanica.org)
12
 * @license	http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
12
 * @license	http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
13
 * @license	http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
13
 * @license	http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
14
 * @version	$Id: GestionnaireException.php 369 2011-10-03 12:47:17Z jpm $$
14
 * @version	$Id: GestionnaireException.php 497 2019-09-17 09:49:05Z killian $$
15
 * @link		/doc/framework/
15
 * @link		/doc/framework/
16
 *
16
 *
17
 */
17
 */
18
class GestionnaireException {
18
class GestionnaireException {
19
	
19
	
20
	const MODE_CLI = 'cli';
20
	const MODE_CLI = 'cli';
21
	
21
	
22
	/** Liste des exceptions enregistrées */
22
	/** Liste des exceptions enregistrées */
23
	private static $exceptions = array();
23
	private static $exceptions = array();
24
 
24
 
25
	/** Détermine si l'on affiche ou non le contexte */
25
	/** Détermine si l'on affiche ou non le contexte */
26
	private static $contexte = false;
26
	private static $contexte = false;
27
 
27
 
28
	 /** Détermine si l'on loggue ou non les erreurs */
28
	 /** Détermine si l'on loggue ou non les erreurs */
29
	private static $logger = false;
29
	private static $logger = false;
30
 
30
 
31
	/** Détermine si l'affichage des erreurs est forcé (true) ou pas (false) à la destruction de la classe */
31
	/** Détermine si l'affichage des erreurs est forcé (true) ou pas (false) à la destruction de la classe */
32
	private static $afficher = false;
32
	private static $afficher = false;
33
 
33
 
34
	/** Definit si php est lancé en ligne de commande ou en mode serveur */
34
	/** Definit si php est lancé en ligne de commande ou en mode serveur */
35
	private static $mode = null ;
35
	private static $mode = null ;
36
 
36
 
37
	/** Tableau des noms des paramètres à définir dans le fichier de config car obligatoirement nécessaire à cette classe.*/
37
	/** Tableau des noms des paramètres à définir dans le fichier de config car obligatoirement nécessaire à cette classe.*/
38
	private static $parametres_obligatoires = array('debogage', 'debogage_contexte', 'log_debogage');
38
	private static $parametres_obligatoires = array('debogage', 'debogage_contexte', 'log_debogage');
39
	
39
	
40
	/** Initialise le Gestionnaire d'exceptions et d'erreur sans tenir comptes des paramêtres de config. */
40
	/** Initialise le Gestionnaire d'exceptions et d'erreur sans tenir comptes des paramêtres de config. */
41
	public static function initialiser() {
41
	public static function initialiser() {
42
		self::$mode = php_sapi_name();
42
		self::$mode = php_sapi_name();
43
		// Désactivation des balises HTML dans les messages d'erreur de PHP en mode ligne de commande
43
		// Désactivation des balises HTML dans les messages d'erreur de PHP en mode ligne de commande
44
		if (self::$mode == self::MODE_CLI) {
44
		if (self::$mode == self::MODE_CLI) {
45
			ini_set('html_errors', 0);
45
			ini_set('html_errors', 0);
46
		} 
46
		} 
47
		
47
		
48
		set_exception_handler(array(get_class(),'gererException'));
48
		set_exception_handler(array(get_class(),'gererException'));
49
		set_error_handler(array(get_class(),'gererErreur'));
49
		set_error_handler(array(get_class(),'gererErreur'));
50
	}
50
	}
51
	
51
	
52
	/** Configure le Gestionnaire d'exceptions et d'erreur à partir des paramêtres de config. */
52
	/** Configure le Gestionnaire d'exceptions et d'erreur à partir des paramêtres de config. */
53
	public static function configurer() {
53
	public static function configurer() {
54
		Config::verifierPresenceParametres(self::$parametres_obligatoires);
54
		Config::verifierPresenceParametres(self::$parametres_obligatoires);
55
		self::$contexte = Config::get('debogage_contexte');
55
		self::$contexte = Config::get('debogage_contexte');
56
		self::$logger = Config::get('log_debogage');
56
		self::$logger = Config::get('log_debogage');
57
		self::$afficher = Config::get('debogage');
57
		self::$afficher = Config::get('debogage');
58
	}
58
	}
59
	
59
	
60
	/**
60
	/**
61
	 * Renvoie le nombre d'exceptions et d'erreurs levées.
61
	 * Renvoie le nombre d'exceptions et d'erreurs levées.
62
	 * @see getExceptions() pour obtenir les exceptions formatées.
62
	 * @see getExceptions() pour obtenir les exceptions formatées.
63
	 * @since 0.3 
63
	 * @since 0.3 
64
	 * @return int le nombre d'exception actuellement levées
64
	 * @return int le nombre d'exception actuellement levées
65
	 */
65
	 */
66
	public static function getExceptionsNbre() {
66
	public static function getExceptionsNbre() {
67
		return count(self::$exceptions);
67
		return count(self::$exceptions);
68
	}
68
	}
69
	
69
	
70
	/** 
70
	/** 
71
	 * Renvoie le booleen définissant si l'on affiche le contexte ou non 
71
	 * Renvoie le booleen définissant si l'on affiche le contexte ou non 
72
	 * @return bool true si on affiche le contexte sinon false. 
72
	 * @return bool true si on affiche le contexte sinon false. 
73
	 */
73
	 */
74
	public static function getContexte() {
74
	public static function getContexte() {
75
		return self::$contexte;
75
		return self::$contexte;
76
	}
76
	}
77
 
77
 
78
	/**
78
	/**
79
	 * Definit si l'on veut afficher le contexte ou non
79
	 * Definit si l'on veut afficher le contexte ou non
80
	 * @param bool true si on veut afficher le contexte, false sinon, par défaut vaut false
80
	 * @param bool true si on veut afficher le contexte, false sinon, par défaut vaut false
81
	 */
81
	 */
82
	public static function setContexte($contexte) {
82
	public static function setContexte($contexte) {
83
		self::$contexte = $contexte;
83
		self::$contexte = $contexte;
84
	}
84
	}
85
 
85
 
86
	/**
86
	/**
87
	 * Fonction de gestion des exceptions, remplace le handler par défaut.
87
	 * Fonction de gestion des exceptions, remplace le handler par défaut.
88
	 * Si une boucle génère de multiple exception (ou erreur) identique une seule sera stockée.
88
	 * Si une boucle génère de multiple exception (ou erreur) identique une seule sera stockée.
89
	 * @param Exception $e l'exception à traiter
89
	 * @param Exception $e l'exception à traiter
90
	 */
90
	 */
91
	public static function gererException(Exception $e) {
91
	public static function gererException(Throwable $e) {
92
		$cle = hash('md5', $e->getMessage().'-'.$e->getFile().'-'.$e->getLine());
92
		$cle = hash('md5', $e->getMessage().'-'.$e->getFile().'-'.$e->getLine());
93
		if (!isset(self::$exceptions[$cle])) {
93
		if (!isset(self::$exceptions[$cle])) {
94
			self::$exceptions[$cle] = $e;
94
			self::$exceptions[$cle] = $e;
95
			self::loggerException($e);
95
			self::loggerException($e);
96
		}
96
		}
97
	}
97
	}
98
 
98
 
99
	/**
99
	/**
100
	 * Gère les erreurs en les convertissant en exceptions (remplace la fonction gestion d'erreurs native de php)
100
	 * Gère les erreurs en les convertissant en exceptions (remplace la fonction gestion d'erreurs native de php)
101
	 * @param int $niveau le niveau de l'erreur
101
	 * @param int $niveau le niveau de l'erreur
102
	 * @param string $message le message associé à l'erreur
102
	 * @param string $message le message associé à l'erreur
103
	 * @param string $fichier le nom du fichier où l'erreur s'est produite
103
	 * @param string $fichier le nom du fichier où l'erreur s'est produite
104
	 * @param int $ligne la ligne où l'erreur s'est produite
104
	 * @param int $ligne la ligne où l'erreur s'est produite
105
	 * @param string $contexte le contexte associé à l'erreur
105
	 * @param string $contexte le contexte associé à l'erreur
106
	 */
106
	 */
107
	public static function gererErreur($niveau,  $message,  $fichier,  $ligne,  $contexte){
107
	public static function gererErreur($niveau,  $message,  $fichier,  $ligne,  $contexte){
108
		// Si un rapport d'erreur existe, création d'une exception
108
		// Si un rapport d'erreur existe, création d'une exception
109
		if (error_reporting() != 0) {
109
		if (error_reporting() != 0) {
110
			$e = new ErrorException($message, 0, $niveau, $fichier, $ligne);
110
			$e = new ErrorException($message, 0, $niveau, $fichier, $ligne);
111
			self::gererException($e);
111
			self::gererException($e);
112
		}
112
		}
113
		return null;
113
		return null;
114
	}
114
	}
115
 
115
 
116
	/**
116
	/**
117
	 * Renvoie les exceptions au format (X)HTML ou bien au format texte suivant le mode d'utilisation de PHP.
117
	 * Renvoie les exceptions au format (X)HTML ou bien au format texte suivant le mode d'utilisation de PHP.
118
	 * @since 0.3
118
	 * @since 0.3
119
	 * @deprecated
119
	 * @deprecated
120
	 * @see getExceptionsFormatees()
120
	 * @see getExceptionsFormatees()
121
	 * @return string les exceptions formatées en texte ou (X)HTML.
121
	 * @return string les exceptions formatées en texte ou (X)HTML.
122
	 */
122
	 */
123
	public static function getExceptions() {
123
	public static function getExceptions() {
124
		return self::getExceptionsFormatees();
124
		return self::getExceptionsFormatees();
125
	}
125
	}
126
	
126
	
127
	/**
127
	/**
128
	 * Renvoie les exceptions au format (X)HTML ou bien au format texte suivant le mode d'utilisation de PHP.
128
	 * Renvoie les exceptions au format (X)HTML ou bien au format texte suivant le mode d'utilisation de PHP.
129
	 * @since 0.3
129
	 * @since 0.3
130
	 * @return string les exceptions formatées en texte ou (X)HTML.
130
	 * @return string les exceptions formatées en texte ou (X)HTML.
131
	 */
131
	 */
132
	public static function getExceptionsFormatees() {
132
	public static function getExceptionsFormatees() {
133
		$retour = '';
133
		$retour = '';
134
		if (self::getExceptionsNbre() > 0) {
134
		if (self::getExceptionsNbre() > 0) {
135
			foreach (self::$exceptions as $cle => $e) {
135
			foreach (self::$exceptions as $cle => $e) {
136
				switch (self::$mode) {
136
				switch (self::$mode) {
137
					case self::MODE_CLI :
137
					case self::MODE_CLI :
138
						$retour .= self::formaterExceptionTxt($e);
138
						$retour .= self::formaterExceptionTxt($e);
139
						break;
139
						break;
140
					default:
140
					default:
141
						$retour .= self::formaterExceptionXhtml($e);
141
						$retour .= self::formaterExceptionXhtml($e);
142
				}
142
				}
143
				// Nous vidons le tableau des exceptions au fur et à mesure pour éviter le réaffichage avec le destructeur.
143
				// Nous vidons le tableau des exceptions au fur et à mesure pour éviter le réaffichage avec le destructeur.
144
				unset(self::$exceptions[$cle]);
144
				unset(self::$exceptions[$cle]);
145
			}
145
			}
146
		}
146
		}
147
		return $retour;
147
		return $retour;
148
	}
148
	}
149
	
149
	
150
	/**
150
	/**
151
	 * Renvoie le tableau d'objets Exception générées par le script PHP triées du niveau de sévérité le plus élevé au moins élevé.
151
	 * Renvoie le tableau d'objets Exception générées par le script PHP triées du niveau de sévérité le plus élevé au moins élevé.
152
	 * Format du tableau :
152
	 * Format du tableau :
153
	 * array{sévérité_1 = array{Exception1, Exception2, Exception3,...}, sévérité_1 =  array{Exception1, Exception2, ...}, ...};
153
	 * array{sévérité_1 = array{Exception1, Exception2, Exception3,...}, sévérité_1 =  array{Exception1, Exception2, ...}, ...};
154
	 * ATTENTION : si vous utilisez cette méthode, c'est à vous de gérer l'affichage des Exceptions. Le gestionnaire d'exception
154
	 * ATTENTION : si vous utilisez cette méthode, c'est à vous de gérer l'affichage des Exceptions. Le gestionnaire d'exception
155
	 * n'enverra plus rien au navigateur ou à la console.
155
	 * n'enverra plus rien au navigateur ou à la console.
156
	 * @since 0.3
156
	 * @since 0.3
157
	 * @return array le tableau trié d'objet Exception.
157
	 * @return array le tableau trié d'objet Exception.
158
	 */
158
	 */
159
	public static function getExceptionsTriees() {
159
	public static function getExceptionsTriees() {
160
		$retour = array();
160
		$retour = array();
161
		if (self::getExceptionsNbre() > 0) {
161
		if (self::getExceptionsNbre() > 0) {
162
			foreach (self::$exceptions as $cle => $e) {
162
			foreach (self::$exceptions as $cle => $e) {
163
				$retour[$e->getSeverity()][] = $e;
163
				$retour[$e->getSeverity()][] = $e;
164
				// Nous vidons le tableau des exceptions au fur et à mesure pour éviter le réaffichage avec le destructeur.
164
				// Nous vidons le tableau des exceptions au fur et à mesure pour éviter le réaffichage avec le destructeur.
165
				unset(self::$exceptions[$cle]);
165
				unset(self::$exceptions[$cle]);
166
			}
166
			}
167
			ksort($retour);
167
			ksort($retour);
168
		}
168
		}
169
		return $retour;
169
		return $retour;
170
	}
170
	}
171
 
171
 
172
	/**
172
	/**
173
	 * Logue une exception donnée sous une forme lisible si self::logger vaut true.
173
	 * Logue une exception donnée sous une forme lisible si self::logger vaut true.
174
	 * @param Exception	$e l'exception à logger
174
	 * @param Exception	$e l'exception à logger
175
	 */
175
	 */
176
	private static function loggerException(Exception $e) {
176
	private static function loggerException(Throwable $e) {
177
		if (self::$logger) {
177
		if (self::$logger) {
178
			$message = self::formaterExceptionTxt($e);
178
			$message = self::formaterExceptionTxt($e);
179
			Log::ajouterEntree('erreurs', $message);
179
			Log::ajouterEntree('erreurs', $message);
180
		}
180
		}
181
	}
181
	}
182
	
182
	
183
	/**
183
	/**
184
	 * Formate une exception de type Notice générée par la classe Debug.
184
	 * Formate une exception de type Notice générée par la classe Debug.
185
	 * Seul le message est gardé car les autres infos font référence à la classe Debug et non à l'endroit où 
185
	 * Seul le message est gardé car les autres infos font référence à la classe Debug et non à l'endroit où 
186
	 * le débug est lancée.
186
	 * le débug est lancée.
187
	 * TODO : faire en sorte d'afficher le fichier et la ligne où le débug est lancé.
187
	 * TODO : faire en sorte d'afficher le fichier et la ligne où le débug est lancé.
188
	 * @since 0.3
188
	 * @since 0.3
189
	 * @param Exception l'exception à formater.
189
	 * @param Exception l'exception à formater.
190
	 */
190
	 */
191
	public static function formaterExceptionDebug(Exception $e) {
191
	public static function formaterExceptionDebug(Throwable $e) {
192
		$txt = '';
192
		$txt = '';
193
		if ($e->getSeverity() == E_USER_NOTICE) {
193
		if ($e->getSeverity() == E_USER_NOTICE) {
194
			$txt = $e->getMessage();
194
			$txt = $e->getMessage();
195
		} else {
195
		} else {
196
			$txt = self::formaterExceptionTxt($e);
196
			$txt = self::formaterExceptionTxt($e);
197
		}
197
		}
198
		return $txt;
198
		return $txt;
199
	}
199
	}
200
	
200
	
201
	/**
201
	/**
202
	 * Formate en texte une exception passée en paramètre.
202
	 * Formate en texte une exception passée en paramètre.
203
	 * @since 0.3
203
	 * @since 0.3
204
	 * @param Exception l'exception à formater.
204
	 * @param Exception l'exception à formater.
205
	 */
205
	 */
206
	public static function formaterExceptionTxt(Exception $e) {
206
	public static function formaterExceptionTxt(Throwable $e) {
207
		$message = '';
207
		$message = '';
208
		$message .= $e->getMessage()."\n";
208
		$message .= $e->getMessage()."\n";
209
		$message .= 'Fichier : '.$e->getFile()."\n";
209
		$message .= 'Fichier : '.$e->getFile()."\n";
210
		$message .= 'Ligne : '.$e->getLine()."\n";
210
		$message .= 'Ligne : '.$e->getLine()."\n";
211
		if (self::getContexte()) {
211
		if (self::getContexte()) {
212
			$message .= 'Contexte : '."\n".print_r($e->getTraceAsString(), true)."\n";
212
			$message .= 'Contexte : '."\n".print_r($e->getTraceAsString(), true)."\n";
213
		}
213
		}
214
		$message .= "\n";
214
		$message .= "\n";
215
		return $message;
215
		return $message;
216
	}
216
	}
217
	
217
	
218
	/**
218
	/**
219
	 * Formate en (X)HTML une exception passée en paramètre.
219
	 * Formate en (X)HTML une exception passée en paramètre.
220
	 * @since 0.3
220
	 * @since 0.3
221
	 * @param Exception l'exception à formater.
221
	 * @param Exception l'exception à formater.
222
	 */
222
	 */
223
	public static function formaterExceptionXhtml(Exception $e) {
223
	public static function formaterExceptionXhtml(Throwable $e) {
224
		$message = '';
224
		$message = '';
225
		$message .= '<div class="debogage">'."\n";
225
		$message .= '<div class="debogage">'."\n";
226
		$message .= $e->getMessage()."\n";
226
		$message .= $e->getMessage()."\n";
227
		$message .= '<span class="debogage_fichier">'.'Fichier : '.$e->getFile().'</span>'."\n";
227
		$message .= '<span class="debogage_fichier">'.'Fichier : '.$e->getFile().'</span>'."\n";
228
		$message .= '<span class="debogage_ligne">'.'Ligne : '.$e->getLine().'</span>'."\n";
228
		$message .= '<span class="debogage_ligne">'.'Ligne : '.$e->getLine().'</span>'."\n";
229
		if (self::getContexte()) {
229
		if (self::getContexte()) {
230
			$message .= '<pre>'."\n";
230
			$message .= '<pre>'."\n";
231
			$message .= '<strong>Contexte : </strong>'."\n".print_r($e->getTraceAsString(), true)."\n";
231
			$message .= '<strong>Contexte : </strong>'."\n".print_r($e->getTraceAsString(), true)."\n";
232
			$message .= '</pre>'."\n";
232
			$message .= '</pre>'."\n";
233
		}
233
		}
234
		$message .= '</div>'."\n";
234
		$message .= '</div>'."\n";
235
		return $message;
235
		return $message;
236
	}
236
	}
237
	
237
	
238
	/**
238
	/**
239
	 * Lors de la destruction de la classe si des exceptions n'ont pas été affichées, et si le débogage est à true, elles sont
239
	 * Lors de la destruction de la classe si des exceptions n'ont pas été affichées, et si le débogage est à true, elles sont
240
	 * affichées. 
240
	 * affichées. 
241
	 */
241
	 */
242
	public function __destruct() {
242
	public function __destruct() {
243
		// Si des erreurs n'ont pas été affichée nous forçons leur affichage
243
		// Si des erreurs n'ont pas été affichée nous forçons leur affichage
244
		if (self::$afficher && self::getExceptionsNbre() > 0) {
244
		if (self::$afficher && self::getExceptionsNbre() > 0) {
245
			echo self::getExceptionsFormatees();
245
			echo self::getExceptionsFormatees();
246
		}
246
		}
247
	}
247
	}
248
 
248
 
249
}
249
}
250
?>
-
 
251
250
?>
-
 
251