Accueil > > > [PHP5] PHP DEBUGGER ET HELPER
[PHP5] PHP DEBUGGER ET HELPER
Information sur la source
Description
[PHP5] ODEBUGGER PACKAGE
Ce package est un outil de debugging.
Il surcharge la gestion des erreurs et des exceptions de PHP, pour utiliser une gestion personnalisée.
Les erreurs sont générées sans s'occuper de la constante error_reporting de php.ini.
Les erreurs sont traduites, affichées, avec le code incréminé, la trduction du message d'erreur, une suggestion de correction, la date.
Les exceptions ne sont pas traduites.
Les erreurs peuvent être loggées dans un fichier XML, et/ou afficher en temps réel.
Il est évident que puisque c'est un outil de debugging, il n'est pas destiné à être utilisé
en production, mais uniquement en développement.
Il peut être utilisé autant pour les débutants, qui y trouveront des cuggestions de correction, et des messages intelligibles, que par les "pros", qui pourront le personnaliser
à loisir pour l'adapter à leurs besoins.
Son utilisation est simple. Divers exemples se trouvent dans les différents fichier 'indexN.php'.
A prévoir bientôt : ajout d'une gestion des exceptions. Ainsi que de pas mal de nouvelles options.
Version 20060612
- localisé
- plusieurs erreurs traduites
- types d'erreur traduits
- 2 types d'affichage : un pour le temps réel, un pour le différé, avec statistiques sommaires.
- très facilement personnalisable :
dans le répertoire templates/ se trouvent les fichiers HTML servant de template pour l'affichage.
Ils peuvent être modifiés à loisir, et on peut en créer facilement de nouveau, tant que l'on respecte la règle
de nommage (voir default.dat et default_log.dat).
default.dat sert à l'affichage temps réel.
default_log.dat à l'affichage en différé (par exemple, pour afficher un fichier log précédent).
Sont associés dans fichiers template CSS dans le répertoire 'css/'.
La traduction des types d'erreurs, et des messages d'erreur sont dans le répertoire 'language/xml/'.
'language' faisant référence au langage. Pour l'instant uniquement FR pour Français.
Le fichier types.xml contient les types et leur traduction.
Le fichier errors.xml contient divers messages d'erreurs, avec le message original, sa traduction, et une suggestion de correction.
ON peut très facilement compléter ce fichier avec ses propres messages, traductions et suggestions, en respectant le flux, bien évidemment.
On peut aussi aisément localiser ces fichiers. Par exemple, pour le localiser en anglais, il suffit de créer un
répertoire 'EN/' (par exemple...), d'y copier ces 2 fichiers, et de les traduire.
On appellera ensuite le debugger ainsi :
$oDebugger = new odebugger ('EN');
HOW TO :
* How to call the debugger :
$oDebugger = new odebugger ('EN');
Where 'EN' is the chosen language.
Check the 'xml/' folder to see which languages are currently supported.
English being the default language, you can call the debugger this way, too, for English :
$oDebugger = new odebugger;
* How to add a new language :
In the xml/ folder, you can find surbolders. Each one contains the XML files for a different language.
'EN/' => English
'FR/' => French.
If you want to add, for example, German, just create a 'GE/' subfolder, and copy both the xml files :
errors.xml and types.xml into the new folder.
Then, edit them.
All you have to do is change the <translation> and <suggestion> nodes in the XML files.
And that's it!
You can then call the debugger in German :
$oDebugger = new odebugger ('GE');
How to add a new error :
Well, just edit the chose language errors.xml file (xml/LANGUAGE/errors.xml), and copy/paste
a node within the <errors></errors> root node. It must follow the others:
<error>
<label>Undefined index:</label>
<translation>An index has been used without being defined</translation>
<suggestion>Check the max and min limits of your array</suggestion>
</error>
Just change the values, save the file, and that's it.
You can, of course, also change an existing node, if you do not like my translations/suggestions ;-)
* How to change the display:
Well, there is currently 2 types of display : realtime, and stats.
IN the folder 'templates/', you can find some files. For example :
default.dat
default_log.dat
default.dat is the default realtime display HTML template, while default_log.dat is the default stat HTML template.
You can create your own, of course. The information supplied by odebugger replace the {INFO_NAME} types of string.
Just make sure you put all the information you want in your templates :-)
For the stats template, there is a slight difference : it has 3 parts.
The first one starts from the...start, and ends on : <--! LINES HERE -->.
This part is fixed. These are the headers!
Then, between <--! LINES HERE -->. and <!-- STATS -->, the logs will be displayed. And of course, the lines here
will be repeated as many times as you have lines in your log.
Then, after <!-- STATS -->, you have your stats :-)
You can set new templates with :
odebugger::HTML
and
odebugger::HTMLLOG
properties. See the part of this documentation about the OPTIONS.
In the 'css/' folder, you can also find files. These are the CSS files used to modify the HTML templates.
default.dat being the CSS for the default.dat HTML template.
default_log.dat being the CSS for the default_log.dat HTML template.
You can also, of course, set them :
odebugger::CSS
and
odebugger::CSSLOG
OPTIONS que l'on peut modifier :
Syntaxe :
$oDebugger -> {OPTION} = {VALEUR};
Par exemple :
$oDebugger -> LINES = 2;
odebugger::LINES => un entier représentant le nombre de lignes à afficher avant et après la ligne où a été détectée l'erreur.
odebugger::HTML => une chaîne contenant le nom du fichier template HTML présent dans le répertoire 'templates', sans son extension.
Sert à afficher le log en mode realtime.
odebugger::CSS => une chaîne contenant le nom du fichier template CSS présent dans le répertoire 'css', sans son extension.
Sert à afficher le log en mode realtime, applique la CSS au template HTML.
odebugger::HTMLLOG => une chaîne contenant le nom du fichier template HTML présent dans le répertoire 'templates', sans son extension.
Sert à afficher le log en mode statistiques (chargement d'un fichier log, ou affichage global de tout le log de la page courante).
odebugger::CSSLOG => une chaîne contenant le nom du fichier template CSS présent dans le répertoire 'css', sans son extension.
Sert à afficher le log en mode statistiques (chargement d'un fichier log, ou affichage global de tout le log de la page courante), applique la CSS au template HTML.
odebugger::REALTIME => booléen true ou false. Active ou désactive le mode realtime (interception et affichage des erreurs au fur et à mesure de l'exécution du script).
odebugger::LOGFILE => booléen true ou false. Active ou désactive le mode 'log to file' (sauvegarde ou non du log complet à la fin de l'exécution du script, dans le répertoire 'logs').
odebugger::ERROR => booléen true ou false. Active ou désactive la gestion des erreurs personnalisée.
odebugger::EXCEPTION => booléen true ou false. Active ou désactive la gestion des exceptions personnalisée.
odebugger::DISABLE => constant type d'erreur. Désactive la gestion d'erreur pour ce type d'erreur (ex: $odebugger -> DISABLE = E_STRICT; va desactiver la gestion des erreurs de type E_STRICT).
odebugger::ENABLE => constant type d'erreur. Active la gestion d'erreur pour ce type d'erreur (ex: $odebugger -> ENABLE = E_STRICT; va réactiver la gestion des erreurs de type E_STRICT).
A propos de ces 2 dernières options, par défaut, TOUS les types d'erreur sont activés.
You can also retrieve these values :
echo $oDebugger -> LINES; // displays 2
METHODS (the ones you can call only) :
odebugger::checkCode (string sString)
Used to check if there are any errors in a string (usually used by retrieving in a string the content of a file. See index3.php to see that in action).
odebugger::loadXML (string sFile)
Used to get an existing log from a file (logs are stored in the 'logs/' folder).
This method erase any previous log (realtime or not).
odebugger::showAll ()
Used to display the whole current log, just as if it was in realtime mode. You can display a loaded log, or the current realtime log.
odebugger::showLog ()
Used to display the whole current log in stats mode. You can display a loaded log, or the current realtime log.
odebugger::saveToFile (optional string sFile)
Used to save the current log to a file. This methods is used automatically when the script ends, if odebugger::LOGFILE is set to true.
But it can be called manually, with a filename.
Source
- <?php
- /**
- * CLASS odebugger
- *
- * @author : johan <barbier_johan@hotmail.com>
- */
- class odebugger {
-
- /**
- * private (string) sAssertion
- * Check if error comes from an essertion or not, if yes, will contain the filename of the evaluated script
- */
- private $sAssertion = null;
- /**
- * private (string) sLang
- * localization string
- */
- private $sLang = 'EN';
-
- /**
- * private (int) iNbLines
- * Number of lines displayed before and after the line of the error
- */
- private $iNbLines = 2;
-
- /**
- * private (array) aOptions
- * Options array
- */
- private $aOptions = array (
- 'REALTIME' => true,
- 'LOG_FILE' => true,
- 'ERROR' => true,
- 'EXCEPTION' => true,
- 'LOGUNIQUE' => true
- );
-
- /**
- * private (string) sTemplateHTML
- * HTML template file for the realtime log
- */
- private $sTemplateHTML = 'default';
- /**
- * private (string) sTemplateCSS
- * CSS template file for the realtime log
- */
- private $sTemplateCSS = 'default';
- /**
- * private (string) sTemplateHTMLLOG
- * HTML template file for the whole log file
- */
- private $sTemplateHTMLLOG = 'default_log';
- /**
- * private (string) sTemplateCSSLOG
- * CSS template file for the whole log file
- */
- private $sTemplateCSSLOG = 'default_log';
- /**
- * private (string) sXmlPath
- * XML locales folder
- */
- private $sXmlPath = 'xml';
- /**
- * private (string) sLogPath
- * LOGS folder
- */
- private $sLogPath = 'logs';
- /**
- * private (string) sTplPath
- * Templates folder
- */
- private $sTplPath = 'templates';
- /**
- * private (string) sCssPath
- * CSS folder
- */
- private $sCssPath = 'css';
- /**
- * private (string) sCurDir
- * Current directory of the script
- */
- private $sCurDir = '';
-
- /**
- * private (string) sCurId
- * Current file unique id
- */
- private $sCurId = '';
-
- /**
- * private (object) oXMLDOC
- * XML LOG Object (DOMDocument object)
- */
- private $oXMLDOC = null;
- /**
- * private (object) oXMLROOT
- * XML LOG root Object (DOMDocument object)
- */
- private $oXMLROOT = null;
- /**
- * private (object) oCurrentNode
- * Current node Object (DOMDocument object)
- */
- private $oCurrentNode = null;
-
- /**
- * private (array) aCanBeSet
- * class properties that can be set via odebugger::__set()
- */
- private $aCanBeSet = array (
- 'LINES' => 'iNbLines',
- 'REALTIME' => "aOptions['REALTIME']",
- 'LOGFILE' => "aOptions['LOG_FILE']",
- 'HTML' => 'sTemplateHTML',
- 'CSS' => 'sTemplateCSS',
- 'HTMLLOG' => 'sTemplateHTMLLOG',
- 'CSSLOG' => 'sTemplateCSSLOG',
- 'ERROR' => "aOptions['ERROR']",
- 'EXCEPTION' => "aOptions['EXCEPTION']",
- 'DISABLE' => "aEnabled",
- 'ENABLE' => "aEnabled",
- 'LOGUNIQUE' => "aOptions['LOGUNIQUE']",
- );
-
- /**
- * private (object) oXMLTYPES
- * XML DOMDocument object with the list of error types and their translation
- */
- private $oXMLTYPES = null;
-
- /**
- * private (object) oXMLERRORS
- * XML DOMDocument object with the list of errors and their translation
- */
- private $oXMLERRORS = null;
-
- /**
- * private (array) aIndex
- * replacement array for the templates
- */
- private $aIndex = array (
- 0 => array (
- '{DATE_TITRE}',
- '{DATE_VALUE}'
- ),
- 1 => array (
- '{TYPE_TITRE}',
- '{TYPE_VALUE}'
- ),
- 2 => array (
- '{MSG_TITRE}',
- '{MSG_VALUE}'
- ),
- 3 => array (
- '{FILE_TITRE}',
- '{FILE_VALUE}'
- ),
- 4 => array (
- '{LINE_TITRE}',
- '{LINE_VALUE}'
- ),
- 5 => array (
- '{MEM_TITRE}',
- '{MEM_VALUE}'
- ),
- 6 => array (
- '{TRANS_TITRE}',
- '{TRANS_VALUE}'
- ),
- 7 => array (
- '{SUGG_TITRE}',
- '{SUGG_VALUE}'
- ),
- 8 => array (
- '{CONTEXT_TITRE}',
- '{CONTEXT_VALUE}'
- ),
- 9 => array (
- '{SOURCE_TITRE}',
- '{SOURCE_VALUE}'
- ),
- 100 => '{TOTAL_STATS}',
- 101 => '{PHP_VERSION}'
- );
-
- /**
- * private (array) aEnabled
- * array of enabled/disabled Error Levels.
- */
- private $aEnabled = array (
- E_ERROR => true,
- E_WARNING => true,
- E_PARSE => true,
- E_NOTICE => true,
- E_CORE_ERROR => true,
- E_CORE_WARNING => true,
- E_COMPILE_ERROR => true,
- E_COMPILE_WARNING => true,
- E_USER_ERROR => true,
- E_USER_WARNING => true,
- E_USER_NOTICE => true,
- E_STRICT => true,
- E_ALL => true
- );
-
- private $aReplace = array (
- ' ' => ' ',
- '>' => '>',
- '<' => '<',
- '&' => '&'
- );
-
- /**
- * public function __construct ()
- * contsructor
- * sets the error_reporting to 0
- * gets the localization dir
- * import all the xml files
- * set the error handler
- * @Param (string) sLang : the localization used
- */
- public function __construct ($sLang = 'EN', $aOptions = array ('XMLPATH' => null, 'LOGPATH' => null, 'TEMPLATEPATH' => null, 'CSSPATH' => null)) {
- @error_reporting (0);
- if (function_exists ('date_default_timezone_get')) {
- $TZ = date_default_timezone_get ();
- date_default_timezone_set ($TZ);
- }
- if (isset ($aOptions['XMLPATH']) && !is_null ($aOptions['XMLPATH']) && file_exists ($aOptions['XMLPATH'])) {
- $this -> sXmlPath = $aOptions['XMLPATH'];
- }
- if (isset ($aOptions['LOGPATH']) && !is_null ($aOptions['LOGPATH']) && file_exists ($aOptions['LOGPATH'])) {
- $this -> sLogPath = $aOptions['LOGPATH'];
- }
- if (isset ($aOptions['TEMPLATEPATH']) && !is_null ($aOptions['TEMPLATEPATH']) && file_exists ($aOptions['TEMPLATEPATH'])) {
- $this -> sTplPath = $aOptions['TEMPLATEPATH'];
- }
- if (isset ($aOptions['CSSPATH']) && !is_null ($aOptions['CSSPATH']) && file_exists ($aOptions['CSSPATH'])) {
- $this -> sCssPath = $aOptions['CSSPATH'];
- }
- $aLnDir = scandir ($this -> sXmlPath);
- if (in_array ($sLang, $aLnDir)) {
- $this -> sLang = $sLang;
- }
-
- set_error_handler (array ($this, 'myErrorHandler'));
- set_exception_handler (array ($this, 'myExceptionHandler'));
- }
-
- private function createLog () {
- if (false === $this -> aOptions['LOGUNIQUE']) {
- $this -> sCurId = date ('Ymd');
- } else {
- $this -> sCurId = date ('Ymd').'_'.uniqid ();
- }
- $sTemp = dirname (__FILE__);
- $aTemp = preg_split('#/|\\\\#', $sTemp);
- array_pop ($aTemp);
- $this -> sCurDir = implode ('/', $aTemp).'/';
- $this -> oXMLERRORS = new DOMDocument;
- $this -> oXMLERRORS -> load ($this -> sXmlPath.'/'.$this -> sLang.'/errors.xml');
- $this -> oXMLTYPES = new DOMDocument;
- $this -> oXMLTYPES -> load ($this -> sXmlPath.'/'.$this -> sLang.'/types.xml');
- if (!is_dir ($this -> sLogPath)) {
- @mkdir ($this -> sLogPath, 0744);
- }
- if (file_exists ($this -> sLogPath.'/'.$this -> sCurId.'_error_log.xml')) {
- $this -> oXMLDOC = DOMDocument::load ($this -> sLogPath.'/'.$this -> sCurId.'_error_log.xml');
- $this -> oXMLROOT = $this -> oXMLDOC -> documentElement;
- } else {
- $this -> oXMLDOC = new DOMDocument ('1.0', 'utf-8');
- $root = $this -> oXMLDOC -> createElement ('ERRORLOG');
- $this -> oXMLROOT = $this -> oXMLDOC -> appendChild ($root);
- }
- }
- /**
- * public function checkCode ()
- * use the assert () function to get the errors in a given string, or a given file
- * @Param (string) sString : the string with the PHP code to evaluate, or the file to evaluate. Usually, it will come from a file via file_get_contents () for example
- * @Return : false if given parameter is not a string.
- */
- public function checkCode ($sCode) {
- if (file_exists ($sCode)) {
- $sString = file_get_contents ($sCode);
- $this -> sAssertion = $sCode;
- } elseif (!is_string ($sCode)) {
- return false;
- } else {
- $sString = $sCode;
- }
- $sString = str_replace (array ('<?php', '<?', '?>'), '', $sString);
- assert_options(ASSERT_ACTIVE, 1);
- assert_options(ASSERT_WARNING, 0);
- assert_options(ASSERT_QUIET_EVAL, 1);
- //assert_options (ASSERT_CALLBACK, array ($this, 'myAssertHandler')); Waiting a bit to improve this part
- assert ($sString);
- assert_options(ASSERT_ACTIVE, 0);
- return true;
- }
-
- /**
- * public function myAssertHandler ()
- * activate the assertion. Right now, does nothing...and is not used.
- * @Param (string) file : the file from which comes the code
- * @Param (int) line : the error line
- * @Param (string) code : the error code
- * @Return : true
- */
- /*
- public function myAssertHandler ($file, $line, $code){
- return true;
- }
- */
- /**
- * private function checkErrorMessage ()
- * try to find the correct trsnalation and suggestion from a given error message
- * @Param (string) sMsg : the PHP error message
- * @Return (array) aTempArr : array with the translation and the suggestion found
- */
- private function checkErrorMessage ($sMsg) {
- //$iLength = strlen ($sMsg);
- $xpath = new DOMXPath($this -> oXMLERRORS);
- $sQueryLabel = '//error/label';
- $oLabelLists = $xpath -> query ($sQueryLabel);
- $aMsg = explode (' ', $sMsg);
- foreach ($oLabelLists as $oLabel) {
- $aLabel = explode (' ', $oLabel -> nodeValue);
- $aDiff = array_diff ($aLabel, $aMsg);
- if (empty ($aDiff)) {
- $aTempArr['TRANSLATION'] = $oLabel -> nextSibling -> nextSibling -> nodeValue;
- $aTempArr['SUGGESTION'] = $oLabel -> nextSibling -> nextSibling -> nextSibling -> nextSibling -> nodeValue;
- return $aTempArr;
- }
- }
- return false;
- }
-
- /**
- * private function checkTypeTrans ()
- * try to find the error type translation
- * @Param (int) cErrno : the PHP constant error type code
- * @Return (string) nodeValue : the translated error type
- */
- private function checkTypeTrans ($cErrno) {
- $xpath = new DOMXPath($this -> oXMLTYPES);
- $sQueryLevel = '//type/level';
- $oLevelList = $xpath -> query ($sQueryLevel);
- foreach ($oLevelList as $oLevel) {
- if (constant ($oLevel -> nodeValue) === $cErrno) {
- return $oLevel -> nextSibling -> nextSibling -> nodeValue;
- }
- }
- return false;
- }
-
- /**
- * public function myExceptionHandler ()
- * the exception handler : builds the XML error log
- * @Param (object) e : the Exception object
- */
- public function myExceptionHandler ($e) {
- if (is_null ($this -> oXMLDOC) || is_null ($this -> oXMLROOT)) {
- $this -> createLog ();
- }
- $sErrStr = $e -> getMessage ();
- $iErrLine = $e -> getLine ();
- $sType = 'Exception '.$e -> getCode ();
- if (is_null ($this -> sAssertion)) {
- $sErrFile = $e -> getFile ();
- } else {
- $sErrFile = $this -> sAssertion;
- $this -> sAssertion = null;
- }
- $aVars['TRACEASSTRING'] = $e -> getTraceAsString ();
- $aTempArr = array ('TRANSLATION' => '', 'SUGGESTION' => '');
-
- $this -> buildLog ($sType, $sErrStr, $sErrFile, $iErrLine, $aTempArr, $aVars);
- }
-
- /**
- * public function myErrorHandler ()
- * the error handler : builds the XML error log
- * @Param (int) cErrno : the PHP constant error type code
- * @Param (string) sErrStr : the PHP error message
- * @Param (string) sErrFile : the file in which the error has been detected
- * @Param (int) iErrLine : the line of the error
- * @Param (array) mVars : the context
- * @Return (boolean)
- */
- public function myErrorHandler ($cErrno, $sErrStr, $sErrFile, $iErrLine, $mVars) {
- if (false === $this -> aEnabled[$cErrno]) {
- return true;
- }
- if (is_null ($this -> oXMLDOC) || is_null ($this -> oXMLROOT)) {
- $this -> createLog ();
- }
- $aTempArr = $this -> checkErrorMessage ($sErrStr);
- $sType = $this -> checkTypeTrans ($cErrno);
- $aVars = array ();
- foreach ($mVars as $sK => $sV) {
- if ((!is_object ($sV) || $sV != $this) && $sK !== 'GLOBALS' && !empty ($sV)) {
- $aVars[$sK] = $sV;
- }
- }
- if (!is_null ($this -> sAssertion)) {
- $sErrFile = $this -> sAssertion;
- $this -> sAssertion = null;
- }
- $this -> buildLog ($sType, $sErrStr, $sErrFile, $iErrLine, $aTempArr, $aVars);
- return true;
- }
-
- /**
- * private function buildLog ()
- * the error handler : builds the XML error log
- * @Param (string) sType : The type of error/exception
- * @Param (string) sErrStr : the PHP error message
- * @Param (string) sErrFile : the file in which the error has been detected
- * @Param (int) iErrLine : the line of the error
- * @Param (string) sVars : the context
- */
- private function buildLog ($sType, $sErrStr, $sErrFile, $iErrLine, $aTempArr, $aVars) {
- $iErrLine --;
- if ($iErrLine < 0) {
- $iErrLine = 0;
- }
- $oNewLog = $this -> oXMLDOC -> createElement ('ERROR');
- $dump = $this -> oXMLROOT -> getElementsByTagName('ERROR');
- $iNewId = $dump -> length + 1;
- $oNewLog = $this -> oXMLROOT -> appendChild ($oNewLog);
- $oNewLog -> setAttribute ('xml:id', '_'.$iNewId);
- $aElem[] = $this -> oXMLDOC -> createElement ('DATE', date ('d-m-Y H:i:s'));
- $aElem[] = $this -> oXMLDOC -> createElement ('TYPE', $sType);
- $sErrStr = utf8_encode ($sErrStr);
- $aElem[] = $this -> oXMLDOC -> createElement ('PHP_MESSAGE', $sErrStr);
- $aElem[] = $this -> oXMLDOC -> createElement ('FILE', $sErrFile);
- $aElem[] = $this -> oXMLDOC -> createElement ('LINE', $iErrLine);
- if (function_exists ('memory_get_usage')) {
- $iMemory = @memory_get_usage ();
- } else {
- $iMemory = 'n/a';
- }
- $aElem[] = $this -> oXMLDOC -> createElement ('MEMORY', $iMemory);
- $aElem[] = $this -> oXMLDOC -> createElement ('TRANSLATION', $aTempArr['TRANSLATION']);
- $aElem[] = $this -> oXMLDOC -> createElement ('SUGGESTION', $aTempArr['SUGGESTION']);
-
- $sContext = utf8_encode (print_r ($aVars, true));
- $sContext = str_replace (array_keys ($this -> aReplace), $this -> aReplace, $sContext);
- $aElem[] = $this -> oXMLDOC -> createElement ('CONTEXT', '<pre>'.$sContext.'</pre>');
- $oSource = $this -> oXMLDOC -> createElement ('SOURCE');
- $aSourceElem = array ();
- foreach ($this -> getLine ($sErrFile, $iErrLine) as $iLine => $sLine) {
- $sLine = utf8_encode ($sLine);
- $sLine = str_replace (array_keys ($this -> aReplace), $this -> aReplace, $sLine);
- if ($iLine === ($iErrLine)) {
- $aSourceElem[] = $this -> oXMLDOC -> createElement ('SOURCE_LINE_ERROR', ' /** ERROR AROUND THIS LINE => */ '.$sLine);
- } else {
- $aSourceElem[] = $this -> oXMLDOC -> createElement ('SOURCE_LINE', $sLine);
- }
- }
- foreach ($aSourceElem as $oSourceElem) {
- $oSource -> appendChild ($oSourceElem);
- }
- foreach ($aElem as $oElem) {
- $oNewLog -> appendChild ($oElem);
- }
- $oNewLog -> appendChild ($oSource);
- $this -> oCurrentNode = $oNewLog;
- if (true === $this -> aOptions['REALTIME']) {
- $this -> printMe ();
- }
- }
- /**
- * private function getLine ()
- * method to get the lines around the detected error
- * @Param (string) sErrFile : the file in which the error has been detected
- * @Param (int) iErrLine : the line of the error
- * @Return (array) aSource : array with each line
- */
- private function getLine ($sErrFile, $iErrLine) {
- $aSource = array ();
- if (file_exists ($sErrFile)) {
- $aLines = file ($sErrFile);
- for ($i = $iErrLine - $this -> iNbLines; $i<= $iErrLine + $this -> iNbLines; $i ++) {
- if (isset ($aLines[$i])) {
- $aSource[$i] = $aLines[$i];
- }
- }
- }
- return $aSource;
- }
-
- /**
- * public function loadXML ()
- * loads an external error log
- * @Param (string) sFile : the error log file to be loaded
- * @Return (boolean)
- */
- public function loadXML ($sFile) {
- if (!file_exists ($this -> sLogPath.'/'.$sFile)) {
- return false;
- }
- if (is_null ($this -> oXMLDOC)) {
- $this -> oXMLDOC = new DOMDocument ('1.0', 'utf-8');
- }
- $this -> oXMLDOC -> load ($this -> sLogPath.'/'.$sFile);
- return true;
- }
-
- /**
- * public function showAll ()
- * show the whole current xml log
- */
- public function showAll () {
- $xpath = new DOMXPath($this -> oXMLDOC);
- $sQuery = '//ERROR';
- $oNodeLists = $xpath -> query ($sQuery);
- foreach ($oNodeLists as $oNodeList) {
- $this -> oCurrentNode = $oNodeList;
- $this -> printMe ();
- }
- }
-
- /**
- * public function showLog ()
- * show the whole current log in a table, with stats (best used after odebugger::loadXML())
- * @Return (string) sHtml : the generated HTML
- */
- public function showLog () {
- $sBaseHtml = file_get_contents ($this -> sTplPath.'/'.$this -> sTemplateHTMLLOG.'.dat');
- $iStartPos = strpos ($sBaseHtml, '<!-- LINES HERE -->');
- $sHtml = substr ($sBaseHtml, 0, $iStartPos);
- $iEndPos = strpos ($sBaseHtml, '<!-- STATS -->');
- $iLength = strlen ($sBaseHtml);
- $sTempHtml = substr ($sBaseHtml, $iStartPos, - ($iLength - $iEndPos));
- $sTempHtmlTotal = '';
- $xpath = new DOMXPath($this -> oXMLDOC);
- $sQuery = '//ERROR';
- $oNodeLists = $xpath -> query ($sQuery);
- foreach ($oNodeLists as $oNodeList) {
- $this -> oCurrentNode = $oNodeList;
- $sTempHtmlTotal .= $this -> printMeLog ($sTempHtml);
- }
- $sHtml .= $sTempHtmlTotal;
- $sQuery = '//ERROR/TYPE';
- $oNodeLists = $xpath -> query ($sQuery);
- foreach ($oNodeLists as $oNodeList) {
- $aTypes[] = $oNodeList -> nodeValue;
- }
- $sHtml .= substr ($sBaseHtml, $iEndPos, ($iLength - 1));
- $aCountType = array_count_values ($aTypes);
- $sCountType = '';
- foreach ($aCountType as $kType => $vType) {
- $sCountType .= $kType.' : '.$vType.'<br />';
- }
- $sVersion = @phpversion ();
- $sHtml = str_replace ($this -> aIndex[100], $sCountType, $sHtml);
- $sHtml = str_replace ($this -> aIndex[101], $sVersion , $sHtml);
- return $sHtml;
- }
-
- /**
- * private function printMe ()
- * display a caught error
- * @Return (string) sHtml : the generated HTML
- */
- private function printMe () {
- $sHtml = file_get_contents ($this -> sTplPath.'/'.$this -> sTemplateHTML.'.dat');
- $nodeList = $this -> oCurrentNode -> childNodes;
- $iId = $this -> oCurrentNode -> getAttribute ('id');
- for ($i = 0; $i < $nodeList -> length; $i++) {
- $sName = $nodeList -> item($i) -> nodeName;
- if ($sName === 'SOURCE') {
- $sourceNodeList = $nodeList -> item($i) -> childNodes;
- $sValeur = '';
- for ($j = 0; $j < $sourceNodeList -> length; $j++) {
- $sValeur .= str_replace (array ('<?php', '?>', '<?'), '', $sourceNodeList -> item($j) -> nodeValue);
- }
- $sValeur = str_replace ($this -> aReplace, array_keys ($this -> aReplace), $sValeur);
- $sValeur = highlight_string ('<?php '."\r\n".$sValeur.'?>', true);
- } else {
- $sValeur = $nodeList -> item($i) -> nodeValue;
- }
- $sId = uniqid().'_'.$iId;
- $aReplacement = array ($sName, $sValeur);
- $sHtml = str_replace ($this -> aIndex[$i], $aReplacement, $sHtml);
- $sHtml = str_replace ('{ID}', $sId, $sHtml);
- }
- echo $sHtml;
- }
-
- /**
- * private function printMeLog ()
- * display a caught error, used by odebugger::showLog()
- * @Return (string) sHtml : the generated HTML
- */
- private function printMeLog ($sHtml) {
- $nodeList = $this -> oCurrentNode -> childNodes;
- $iId = $this -> oCurrentNode -> getAttribute ('id');
- for ($i = 0; $i < $nodeList -> length; $i++) {
- if ($nodeList -> item($i) -> nodeName === 'SOURCE') {
- $sourceNodeList = $nodeList -> item($i) -> childNodes;
- $sValeur = '';
- for ($j = 0; $j < $sourceNodeList -> length; $j++) {
- $sValeur .= str_replace (array ('<?php', '?>', '<?'), '', $sourceNodeList -> item($j) -> nodeValue);
- }
- $sValeur = str_replace ($this -> aReplace, array_keys ($this -> aReplace), $sValeur);
- $sValeur = highlight_string ('<?php '."\r\n".$sValeur.'?>', true);
- } else {
- $sValeur = $nodeList -> item($i) -> nodeValue;
- }
- $sHtml = str_replace ($this -> aIndex[$i][1], $sValeur, $sHtml);
- $sId = uniqid().'_'.$iId;
- $sHtml = str_replace ('{ID}', $sId, $sHtml);
- }
- return $sHtml;
- }
-
- /**
- * public function saveToFile ()
- * save the current log to a given file
- * @Param (string) sFile : name of the log file
- * @Return (boolean)
- */
- public function saveToFile ($sFile = null) {
- if (is_null ($this -> oXMLDOC)) {
- return true;
- }
- if ($sFile === null) {
- $sFile = $this -> sCurId.'_error_log.xml';
- }
- /*
- if (file_exists ($this -> sCurDir.$this -> sLogPath.'/'.$sFile)) {
- $this -> oXMLDOC -> save ($this -> sCurDir.$this -> sLogPath.'/'.$sFile);
- chmod ($this -> sCurDir.$this -> sLogPath.'/'.$sFile, 0775);
- } else {
- $this -> oXMLDOC -> save ($this -> sLogPath.'/'.$sFile);
- chmod ($this -> sLogPath.'/'.$sFile, 0775);
- }
- */
- if ($this -> sLogPath === 'logs') {
- $this -> oXMLDOC -> save ($this -> sCurDir.$this -> sLogPath.'/'.$sFile);
- chmod ($this -> sCurDir.$this -> sLogPath.'/'.$sFile, 0775);
- } else {
- $this -> oXMLDOC -> save ($this -> sLogPath.'/'.$sFile);
- chmod ($this -> sLogPath.'/'.$sFile, 0775);
- }
- return true;
- }
-
- /**
- * public function __destruct ()
- * destructor
- * will save the log to a file if the LOG_FILE option is set to true
- */
- public function __destruct () {
- if (true === $this -> aOptions['LOG_FILE']) {
- $this -> saveToFile ();
- }
- }
-
- /**
- * public function __set ()
- * allows some properties to be set
- * @Param (string) sProp : name of the property
- * @Param (mixed) mVal : the value to be given to the property
- * @Return (boolean) false if failed, true if succeeded
- */
- public function __set ($sProp, $mVal) {
- if (false === array_key_exists ($sProp, $this -> aCanBeSet)) {
- return false;
- }
- switch ($sProp) {
- case 'LINES' :
- if (!is_int ($mVal)) {
- return false;
- }
- $this -> iNbLines = $mVal;
- break;
- case 'HTML' :
- if (!file_exists ($this -> sTplPath.'/'.$mVal.'.dat')) {
- return false;
- }
- $this -> sTemplateHTML = $mVal;
- break;
- case 'HTMLLOG' :
- if (!file_exists ($this -> sTplPath.'/'.$mVal.'.dat')) {
- return false;
- }
- $this -> sTemplateHTMLLOG = $mVal;
- break;
- case 'CSS' :
- if (!file_exists ($this -> sCssPath.'/'.$mVal.'.dat')) {
- return false;
- }
- $this -> sTemplateCSS = $mVal;
- readfile ($this -> sCssPath.'/'.$mVal.'.dat');
- break;
- case 'CSSLOG' :
- if (!file_exists ($this -> sCssPath.'/'.$mVal.'.dat')) {
- return false;
- }
- $this -> sTemplateCSSLOG = $mVal;
- readfile ($this -> sCssPath.'/'.$mVal.'.dat');
- break;
- case 'REALTIME' :
- if (!is_bool ($mVal)) {
- return false;
- }
- $this -> aOptions['REALTIME'] = $mVal;
- break;
- case 'LOGFILE' :
- if (!is_bool ($mVal)) {
- return false;
- }
- $this -> aOptions['LOG_FILE'] = $mVal;
- break;
- case 'LOGUNIQUE' :
- if (!is_bool ($mVal)) {
- return false;
- }
- $this -> aOptions['LOGUNIQUE'] = $mVal;
- break;
- case 'ERROR' :
- if (!is_bool ($mVal)) {
- return false;
- }
- $this -> aOptions['ERROR'] = $mVal;
- if (true === $mVal) {
- set_error_handler (array ($this, 'myErrorHandler'));
- } else {
- restore_error_handler ();
- }
- break;
- case 'EXCEPTION' :
- if (!is_bool ($mVal)) {
- return false;
- }
- $this -> aOptions['EXCEPTION'] = $mVal;
- if (true === $mVal) {
- set_exception_handler (array ($this, 'myExceptionHandler'));
- } else {
- restore_exception_handler ();
- }
- break;
- case 'ENABLE' :
- if (!array_key_exists ($mVal, $this -> aEnabled)) {
- return false;
- }
- $this -> aEnabled[$mVal] = true;
- break;
- case 'DISABLE' :
- if (!array_key_exists ($mVal, $this -> aEnabled)) {
- return false;
- }
- $this -> aEnabled[$mVal] = false;
- break;
- default:
- return false;
- break;
- }
- return true;
- }
-
- /**
- * public function __get ()
- * allows some properties to be get
- * @Param (string) sProp : name of the property
- * @Return (boolean) false if failed, value of the property if succeeded
- */
- public function __get ($sProp) {
- if (false === array_key_exists ($sProp, $this -> aCanBeSet)) {
- return false;
- }
- $sRealProp = $this -> aCanBeSet[$sProp];
- return $this -> $sRealProp;
- }
- }
- ?>
<?php
/**
* CLASS odebugger
*
* @author : johan <barbier_johan@hotmail.com>
*/
class odebugger {
/**
* private (string) sAssertion
* Check if error comes from an essertion or not, if yes, will contain the filename of the evaluated script
*/
private $sAssertion = null;
/**
* private (string) sLang
* localization string
*/
private $sLang = 'EN';
/**
* private (int) iNbLines
* Number of lines displayed before and after the line of the error
*/
private $iNbLines = 2;
/**
* private (array) aOptions
* Options array
*/
private $aOptions = array (
'REALTIME' => true,
'LOG_FILE' => true,
'ERROR' => true,
'EXCEPTION' => true,
'LOGUNIQUE' => true
);
/**
* private (string) sTemplateHTML
* HTML template file for the realtime log
*/
private $sTemplateHTML = 'default';
/**
* private (string) sTemplateCSS
* CSS template file for the realtime log
*/
private $sTemplateCSS = 'default';
/**
* private (string) sTemplateHTMLLOG
* HTML template file for the whole log file
*/
private $sTemplateHTMLLOG = 'default_log';
/**
* private (string) sTemplateCSSLOG
* CSS template file for the whole log file
*/
private $sTemplateCSSLOG = 'default_log';
/**
* private (string) sXmlPath
* XML locales folder
*/
private $sXmlPath = 'xml';
/**
* private (string) sLogPath
* LOGS folder
*/
private $sLogPath = 'logs';
/**
* private (string) sTplPath
* Templates folder
*/
private $sTplPath = 'templates';
/**
* private (string) sCssPath
* CSS folder
*/
private $sCssPath = 'css';
/**
* private (string) sCurDir
* Current directory of the script
*/
private $sCurDir = '';
/**
* private (string) sCurId
* Current file unique id
*/
private $sCurId = '';
/**
* private (object) oXMLDOC
* XML LOG Object (DOMDocument object)
*/
private $oXMLDOC = null;
/**
* private (object) oXMLROOT
* XML LOG root Object (DOMDocument object)
*/
private $oXMLROOT = null;
/**
* private (object) oCurrentNode
* Current node Object (DOMDocument object)
*/
private $oCurrentNode = null;
/**
* private (array) aCanBeSet
* class properties that can be set via odebugger::__set()
*/
private $aCanBeSet = array (
'LINES' => 'iNbLines',
'REALTIME' => "aOptions['REALTIME']",
'LOGFILE' => "aOptions['LOG_FILE']",
'HTML' => 'sTemplateHTML',
'CSS' => 'sTemplateCSS',
'HTMLLOG' => 'sTemplateHTMLLOG',
'CSSLOG' => 'sTemplateCSSLOG',
'ERROR' => "aOptions['ERROR']",
'EXCEPTION' => "aOptions['EXCEPTION']",
'DISABLE' => "aEnabled",
'ENABLE' => "aEnabled",
'LOGUNIQUE' => "aOptions['LOGUNIQUE']",
);
/**
* private (object) oXMLTYPES
* XML DOMDocument object with the list of error types and their translation
*/
private $oXMLTYPES = null;
/**
* private (object) oXMLERRORS
* XML DOMDocument object with the list of errors and their translation
*/
private $oXMLERRORS = null;
/**
* private (array) aIndex
* replacement array for the templates
*/
private $aIndex = array (
0 => array (
'{DATE_TITRE}',
'{DATE_VALUE}'
),
1 => array (
'{TYPE_TITRE}',
'{TYPE_VALUE}'
),
2 => array (
'{MSG_TITRE}',
'{MSG_VALUE}'
),
3 => array (
'{FILE_TITRE}',
'{FILE_VALUE}'
),
4 => array (
'{LINE_TITRE}',
'{LINE_VALUE}'
),
5 => array (
'{MEM_TITRE}',
'{MEM_VALUE}'
),
6 => array (
'{TRANS_TITRE}',
'{TRANS_VALUE}'
),
7 => array (
'{SUGG_TITRE}',
'{SUGG_VALUE}'
),
8 => array (
'{CONTEXT_TITRE}',
'{CONTEXT_VALUE}'
),
9 => array (
'{SOURCE_TITRE}',
'{SOURCE_VALUE}'
),
100 => '{TOTAL_STATS}',
101 => '{PHP_VERSION}'
);
/**
* private (array) aEnabled
* array of enabled/disabled Error Levels.
*/
private $aEnabled = array (
E_ERROR => true,
E_WARNING => true,
E_PARSE => true,
E_NOTICE => true,
E_CORE_ERROR => true,
E_CORE_WARNING => true,
E_COMPILE_ERROR => true,
E_COMPILE_WARNING => true,
E_USER_ERROR => true,
E_USER_WARNING => true,
E_USER_NOTICE => true,
E_STRICT => true,
E_ALL => true
);
private $aReplace = array (
' ' => ' ',
'>' => '>',
'<' => '<',
'&' => '&'
);
/**
* public function __construct ()
* contsructor
* sets the error_reporting to 0
* gets the localization dir
* import all the xml files
* set the error handler
* @Param (string) sLang : the localization used
*/
public function __construct ($sLang = 'EN', $aOptions = array ('XMLPATH' => null, 'LOGPATH' => null, 'TEMPLATEPATH' => null, 'CSSPATH' => null)) {
@error_reporting (0);
if (function_exists ('date_default_timezone_get')) {
$TZ = date_default_timezone_get ();
date_default_timezone_set ($TZ);
}
if (isset ($aOptions['XMLPATH']) && !is_null ($aOptions['XMLPATH']) && file_exists ($aOptions['XMLPATH'])) {
$this -> sXmlPath = $aOptions['XMLPATH'];
}
if (isset ($aOptions['LOGPATH']) && !is_null ($aOptions['LOGPATH']) && file_exists ($aOptions['LOGPATH'])) {
$this -> sLogPath = $aOptions['LOGPATH'];
}
if (isset ($aOptions['TEMPLATEPATH']) && !is_null ($aOptions['TEMPLATEPATH']) && file_exists ($aOptions['TEMPLATEPATH'])) {
$this -> sTplPath = $aOptions['TEMPLATEPATH'];
}
if (isset ($aOptions['CSSPATH']) && !is_null ($aOptions['CSSPATH']) && file_exists ($aOptions['CSSPATH'])) {
$this -> sCssPath = $aOptions['CSSPATH'];
}
$aLnDir = scandir ($this -> sXmlPath);
if (in_array ($sLang, $aLnDir)) {
$this -> sLang = $sLang;
}
set_error_handler (array ($this, 'myErrorHandler'));
set_exception_handler (array ($this, 'myExceptionHandler'));
}
private function createLog () {
if (false === $this -> aOptions['LOGUNIQUE']) {
$this -> sCurId = date ('Ymd');
} else {
$this -> sCurId = date ('Ymd').'_'.uniqid ();
}
$sTemp = dirname (__FILE__);
$aTemp = preg_split('#/|\\\\#', $sTemp);
array_pop ($aTemp);
$this -> sCurDir = implode ('/', $aTemp).'/';
$this -> oXMLERRORS = new DOMDocument;
$this -> oXMLERRORS -> load ($this -> sXmlPath.'/'.$this -> sLang.'/errors.xml');
$this -> oXMLTYPES = new DOMDocument;
$this -> oXMLTYPES -> load ($this -> sXmlPath.'/'.$this -> sLang.'/types.xml');
if (!is_dir ($this -> sLogPath)) {
@mkdir ($this -> sLogPath, 0744);
}
if (file_exists ($this -> sLogPath.'/'.$this -> sCurId.'_error_log.xml')) {
$this -> oXMLDOC = DOMDocument::load ($this -> sLogPath.'/'.$this -> sCurId.'_error_log.xml');
$this -> oXMLROOT = $this -> oXMLDOC -> documentElement;
} else {
$this -> oXMLDOC = new DOMDocument ('1.0', 'utf-8');
$root = $this -> oXMLDOC -> createElement ('ERRORLOG');
$this -> oXMLROOT = $this -> oXMLDOC -> appendChild ($root);
}
}
/**
* public function checkCode ()
* use the assert () function to get the errors in a given string, or a given file
* @Param (string) sString : the string with the PHP code to evaluate, or the file to evaluate. Usually, it will come from a file via file_get_contents () for example
* @Return : false if given parameter is not a string.
*/
public function checkCode ($sCode) {
if (file_exists ($sCode)) {
$sString = file_get_contents ($sCode);
$this -> sAssertion = $sCode;
} elseif (!is_string ($sCode)) {
return false;
} else {
$sString = $sCode;
}
$sString = str_replace (array ('<?php', '<?', '?>'), '', $sString);
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_QUIET_EVAL, 1);
//assert_options (ASSERT_CALLBACK, array ($this, 'myAssertHandler')); Waiting a bit to improve this part
assert ($sString);
assert_options(ASSERT_ACTIVE, 0);
return true;
}
/**
* public function myAssertHandler ()
* activate the assertion. Right now, does nothing...and is not used.
* @Param (string) file : the file from which comes the code
* @Param (int) line : the error line
* @Param (string) code : the error code
* @Return : true
*/
/*
public function myAssertHandler ($file, $line, $code){
return true;
}
*/
/**
* private function checkErrorMessage ()
* try to find the correct trsnalation and suggestion from a given error message
* @Param (string) sMsg : the PHP error message
* @Return (array) aTempArr : array with the translation and the suggestion found
*/
private function checkErrorMessage ($sMsg) {
//$iLength = strlen ($sMsg);
$xpath = new DOMXPath($this -> oXMLERRORS);
$sQueryLabel = '//error/label';
$oLabelLists = $xpath -> query ($sQueryLabel);
$aMsg = explode (' ', $sMsg);
foreach ($oLabelLists as $oLabel) {
$aLabel = explode (' ', $oLabel -> nodeValue);
$aDiff = array_diff ($aLabel, $aMsg);
if (empty ($aDiff)) {
$aTempArr['TRANSLATION'] = $oLabel -> nextSibling -> nextSibling -> nodeValue;
$aTempArr['SUGGESTION'] = $oLabel -> nextSibling -> nextSibling -> nextSibling -> nextSibling -> nodeValue;
return $aTempArr;
}
}
return false;
}
/**
* private function checkTypeTrans ()
* try to find the error type translation
* @Param (int) cErrno : the PHP constant error type code
* @Return (string) nodeValue : the translated error type
*/
private function checkTypeTrans ($cErrno) {
$xpath = new DOMXPath($this -> oXMLTYPES);
$sQueryLevel = '//type/level';
$oLevelList = $xpath -> query ($sQueryLevel);
foreach ($oLevelList as $oLevel) {
if (constant ($oLevel -> nodeValue) === $cErrno) {
return $oLevel -> nextSibling -> nextSibling -> nodeValue;
}
}
return false;
}
/**
* public function myExceptionHandler ()
* the exception handler : builds the XML error log
* @Param (object) e : the Exception object
*/
public function myExceptionHandler ($e) {
if (is_null ($this -> oXMLDOC) || is_null ($this -> oXMLROOT)) {
$this -> createLog ();
}
$sErrStr = $e -> getMessage ();
$iErrLine = $e -> getLine ();
$sType = 'Exception '.$e -> getCode ();
if (is_null ($this -> sAssertion)) {
$sErrFile = $e -> getFile ();
} else {
$sErrFile = $this -> sAssertion;
$this -> sAssertion = null;
}
$aVars['TRACEASSTRING'] = $e -> getTraceAsString ();
$aTempArr = array ('TRANSLATION' => '', 'SUGGESTION' => '');
$this -> buildLog ($sType, $sErrStr, $sErrFile, $iErrLine, $aTempArr, $aVars);
}
/**
* public function myErrorHandler ()
* the error handler : builds the XML error log
* @Param (int) cErrno : the PHP constant error type code
* @Param (string) sErrStr : the PHP error message
* @Param (string) sErrFile : the file in which the error has been detected
* @Param (int) iErrLine : the line of the error
* @Param (array) mVars : the context
* @Return (boolean)
*/
public function myErrorHandler ($cErrno, $sErrStr, $sErrFile, $iErrLine, $mVars) {
if (false === $this -> aEnabled[$cErrno]) {
return true;
}
if (is_null ($this -> oXMLDOC) || is_null ($this -> oXMLROOT)) {
$this -> createLog ();
}
$aTempArr = $this -> checkErrorMessage ($sErrStr);
$sType = $this -> checkTypeTrans ($cErrno);
$aVars = array ();
foreach ($mVars as $sK => $sV) {
if ((!is_object ($sV) || $sV != $this) && $sK !== 'GLOBALS' && !empty ($sV)) {
$aVars[$sK] = $sV;
}
}
if (!is_null ($this -> sAssertion)) {
$sErrFile = $this -> sAssertion;
$this -> sAssertion = null;
}
$this -> buildLog ($sType, $sErrStr, $sErrFile, $iErrLine, $aTempArr, $aVars);
return true;
}
/**
* private function buildLog ()
* the error handler : builds the XML error log
* @Param (string) sType : The type of error/exception
* @Param (string) sErrStr : the PHP error message
* @Param (string) sErrFile : the file in which the error has been detected
* @Param (int) iErrLine : the line of the error
* @Param (string) sVars : the context
*/
private function buildLog ($sType, $sErrStr, $sErrFile, $iErrLine, $aTempArr, $aVars) {
$iErrLine --;
if ($iErrLine < 0) {
$iErrLine = 0;
}
$oNewLog = $this -> oXMLDOC -> createElement ('ERROR');
$dump = $this -> oXMLROOT -> getElementsByTagName('ERROR');
$iNewId = $dump -> length + 1;
$oNewLog = $this -> oXMLROOT -> appendChild ($oNewLog);
$oNewLog -> setAttribute ('xml:id', '_'.$iNewId);
$aElem[] = $this -> oXMLDOC -> createElement ('DATE', date ('d-m-Y H:i:s'));
$aElem[] = $this -> oXMLDOC -> createElement ('TYPE', $sType);
$sErrStr = utf8_encode ($sErrStr);
$aElem[] = $this -> oXMLDOC -> createElement ('PHP_MESSAGE', $sErrStr);
$aElem[] = $this -> oXMLDOC -> createElement ('FILE', $sErrFile);
$aElem[] = $this -> oXMLDOC -> createElement ('LINE', $iErrLine);
if (function_exists ('memory_get_usage')) {
$iMemory = @memory_get_usage ();
} else {
$iMemory = 'n/a';
}
$aElem[] = $this -> oXMLDOC -> createElement ('MEMORY', $iMemory);
$aElem[] = $this -> oXMLDOC -> createElement ('TRANSLATION', $aTempArr['TRANSLATION']);
$aElem[] = $this -> oXMLDOC -> createElement ('SUGGESTION', $aTempArr['SUGGESTION']);
$sContext = utf8_encode (print_r ($aVars, true));
$sContext = str_replace (array_keys ($this -> aReplace), $this -> aReplace, $sContext);
$aElem[] = $this -> oXMLDOC -> createElement ('CONTEXT', '<pre>'.$sContext.'</pre>');
$oSource = $this -> oXMLDOC -> createElement ('SOURCE');
$aSourceElem = array ();
foreach ($this -> getLine ($sErrFile, $iErrLine) as $iLine => $sLine) {
$sLine = utf8_encode ($sLine);
$sLine = str_replace (array_keys ($this -> aReplace), $this -> aReplace, $sLine);
if ($iLine === ($iErrLine)) {
$aSourceElem[] = $this -> oXMLDOC -> createElement ('SOURCE_LINE_ERROR', ' /** ERROR AROUND THIS LINE => */ '.$sLine);
} else {
$aSourceElem[] = $this -> oXMLDOC -> createElement ('SOURCE_LINE', $sLine);
}
}
foreach ($aSourceElem as $oSourceElem) {
$oSource -> appendChild ($oSourceElem);
}
foreach ($aElem as $oElem) {
$oNewLog -> appendChild ($oElem);
}
$oNewLog -> appendChild ($oSource);
$this -> oCurrentNode = $oNewLog;
if (true === $this -> aOptions['REALTIME']) {
$this -> printMe ();
}
}
/**
* private function getLine ()
* method to get the lines around the detected error
* @Param (string) sErrFile : the file in which the error has been detected
* @Param (int) iErrLine : the line of the error
* @Return (array) aSource : array with each line
*/
private function getLine ($sErrFile, $iErrLine) {
$aSource = array ();
if (file_exists ($sErrFile)) {
$aLines = file ($sErrFile);
for ($i = $iErrLine - $this -> iNbLines; $i<= $iErrLine + $this -> iNbLines; $i ++) {
if (isset ($aLines[$i])) {
$aSource[$i] = $aLines[$i];
}
}
}
return $aSource;
}
/**
* public function loadXML ()
* loads an external error log
* @Param (string) sFile : the error log file to be loaded
* @Return (boolean)
*/
public function loadXML ($sFile) {
if (!file_exists ($this -> sLogPath.'/'.$sFile)) {
return false;
}
if (is_null ($this -> oXMLDOC)) {
$this -> oXMLDOC = new DOMDocument ('1.0', 'utf-8');
}
$this -> oXMLDOC -> load ($this -> sLogPath.'/'.$sFile);
return true;
}
/**
* public function showAll ()
* show the whole current xml log
*/
public function showAll () {
$xpath = new DOMXPath($this -> oXMLDOC);
$sQuery = '//ERROR';
$oNodeLists = $xpath -> query ($sQuery);
foreach ($oNodeLists as $oNodeList) {
$this -> oCurrentNode = $oNodeList;
$this -> printMe ();
}
}
/**
* public function showLog ()
* show the whole current log in a table, with stats (best used after odebugger::loadXML())
* @Return (string) sHtml : the generated HTML
*/
public function showLog () {
$sBaseHtml = file_get_contents ($this -> sTplPath.'/'.$this -> sTemplateHTMLLOG.'.dat');
$iStartPos = strpos ($sBaseHtml, '<!-- LINES HERE -->');
$sHtml = substr ($sBaseHtml, 0, $iStartPos);
$iEndPos = strpos ($sBaseHtml, '<!-- STATS -->');
$iLength = strlen ($sBaseHtml);
$sTempHtml = substr ($sBaseHtml, $iStartPos, - ($iLength - $iEndPos));
$sTempHtmlTotal = '';
$xpath = new DOMXPath($this -> oXMLDOC);
$sQuery = '//ERROR';
$oNodeLists = $xpath -> query ($sQuery);
foreach ($oNodeLists as $oNodeList) {
$this -> oCurrentNode = $oNodeList;
$sTempHtmlTotal .= $this -> printMeLog ($sTempHtml);
}
$sHtml .= $sTempHtmlTotal;
$sQuery = '//ERROR/TYPE';
$oNodeLists = $xpath -> query ($sQuery);
foreach ($oNodeLists as $oNodeList) {
$aTypes[] = $oNodeList -> nodeValue;
}
$sHtml .= substr ($sBaseHtml, $iEndPos, ($iLength - 1));
$aCountType = array_count_values ($aTypes);
$sCountType = '';
foreach ($aCountType as $kType => $vType) {
$sCountType .= $kType.' : '.$vType.'<br />';
}
$sVersion = @phpversion ();
$sHtml = str_replace ($this -> aIndex[100], $sCountType, $sHtml);
$sHtml = str_replace ($this -> aIndex[101], $sVersion , $sHtml);
return $sHtml;
}
/**
* private function printMe ()
* display a caught error
* @Return (string) sHtml : the generated HTML
*/
private function printMe () {
$sHtml = file_get_contents ($this -> sTplPath.'/'.$this -> sTemplateHTML.'.dat');
$nodeList = $this -> oCurrentNode -> childNodes;
$iId = $this -> oCurrentNode -> getAttribute ('id');
for ($i = 0; $i < $nodeList -> length; $i++) {
$sName = $nodeList -> item($i) -> nodeName;
if ($sName === 'SOURCE') {
$sourceNodeList = $nodeList -> item($i) -> childNodes;
$sValeur = '';
for ($j = 0; $j < $sourceNodeList -> length; $j++) {
$sValeur .= str_replace (array ('<?php', '?>', '<?'), '', $sourceNodeList -> item($j) -> nodeValue);
}
$sValeur = str_replace ($this -> aReplace, array_keys ($this -> aReplace), $sValeur);
$sValeur = highlight_string ('<?php '."\r\n".$sValeur.'?>', true);
} else {
$sValeur = $nodeList -> item($i) -> nodeValue;
}
$sId = uniqid().'_'.$iId;
$aReplacement = array ($sName, $sValeur);
$sHtml = str_replace ($this -> aIndex[$i], $aReplacement, $sHtml);
$sHtml = str_replace ('{ID}', $sId, $sHtml);
}
echo $sHtml;
}
/**
* private function printMeLog ()
* display a caught error, used by odebugger::showLog()
* @Return (string) sHtml : the generated HTML
*/
private function printMeLog ($sHtml) {
$nodeList = $this -> oCurrentNode -> childNodes;
$iId = $this -> oCurrentNode -> getAttribute ('id');
for ($i = 0; $i < $nodeList -> length; $i++) {
if ($nodeList -> item($i) -> nodeName === 'SOURCE') {
$sourceNodeList = $nodeList -> item($i) -> childNodes;
$sValeur = '';
for ($j = 0; $j < $sourceNodeList -> length; $j++) {
$sValeur .= str_replace (array ('<?php', '?>', '<?'), '', $sourceNodeList -> item($j) -> nodeValue);
}
$sValeur = str_replace ($this -> aReplace, array_keys ($this -> aReplace), $sValeur);
$sValeur = highlight_string ('<?php '."\r\n".$sValeur.'?>', true);
} else {
$sValeur = $nodeList -> item($i) -> nodeValue;
}
$sHtml = str_replace ($this -> aIndex[$i][1], $sValeur, $sHtml);
$sId = uniqid().'_'.$iId;
$sHtml = str_replace ('{ID}', $sId, $sHtml);
}
return $sHtml;
}
/**
* public function saveToFile ()
* save the current log to a given file
* @Param (string) sFile : name of the log file
* @Return (boolean)
*/
public function saveToFile ($sFile = null) {
if (is_null ($this -> oXMLDOC)) {
return true;
}
if ($sFile === null) {
$sFile = $this -> sCurId.'_error_log.xml';
}
/*
if (file_exists ($this -> sCurDir.$this -> sLogPath.'/'.$sFile)) {
$this -> oXMLDOC -> save ($this -> sCurDir.$this -> sLogPath.'/'.$sFile);
chmod ($this -> sCurDir.$this -> sLogPath.'/'.$sFile, 0775);
} else {
$this -> oXMLDOC -> save ($this -> sLogPath.'/'.$sFile);
chmod ($this -> sLogPath.'/'.$sFile, 0775);
}
*/
if ($this -> sLogPath === 'logs') {
$this -> oXMLDOC -> save ($this -> sCurDir.$this -> sLogPath.'/'.$sFile);
chmod ($this -> sCurDir.$this -> sLogPath.'/'.$sFile, 0775);
} else {
$this -> oXMLDOC -> save ($this -> sLogPath.'/'.$sFile);
chmod ($this -> sLogPath.'/'.$sFile, 0775);
}
return true;
}
/**
* public function __destruct ()
* destructor
* will save the log to a file if the LOG_FILE option is set to true
*/
public function __destruct () {
if (true === $this -> aOptions['LOG_FILE']) {
$this -> saveToFile ();
}
}
/**
* public function __set ()
* allows some properties to be set
* @Param (string) sProp : name of the property
* @Param (mixed) mVal : the value to be given to the property
* @Return (boolean) false if failed, true if succeeded
*/
public function __set ($sProp, $mVal) {
if (false === array_key_exists ($sProp, $this -> aCanBeSet)) {
return false;
}
switch ($sProp) {
case 'LINES' :
if (!is_int ($mVal)) {
return false;
}
$this -> iNbLines = $mVal;
break;
case 'HTML' :
if (!file_exists ($this -> sTplPath.'/'.$mVal.'.dat')) {
return false;
}
$this -> sTemplateHTML = $mVal;
break;
case 'HTMLLOG' :
if (!file_exists ($this -> sTplPath.'/'.$mVal.'.dat')) {
return false;
}
$this -> sTemplateHTMLLOG = $mVal;
break;
case 'CSS' :
if (!file_exists ($this -> sCssPath.'/'.$mVal.'.dat')) {
return false;
}
$this -> sTemplateCSS = $mVal;
readfile ($this -> sCssPath.'/'.$mVal.'.dat');
break;
case 'CSSLOG' :
if (!file_exists ($this -> sCssPath.'/'.$mVal.'.dat')) {
return false;
}
$this -> sTemplateCSSLOG = $mVal;
readfile ($this -> sCssPath.'/'.$mVal.'.dat');
break;
case 'REALTIME' :
if (!is_bool ($mVal)) {
return false;
}
$this -> aOptions['REALTIME'] = $mVal;
break;
case 'LOGFILE' :
if (!is_bool ($mVal)) {
return false;
}
$this -> aOptions['LOG_FILE'] = $mVal;
break;
case 'LOGUNIQUE' :
if (!is_bool ($mVal)) {
return false;
}
$this -> aOptions['LOGUNIQUE'] = $mVal;
break;
case 'ERROR' :
if (!is_bool ($mVal)) {
return false;
}
$this -> aOptions['ERROR'] = $mVal;
if (true === $mVal) {
set_error_handler (array ($this, 'myErrorHandler'));
} else {
restore_error_handler ();
}
break;
case 'EXCEPTION' :
if (!is_bool ($mVal)) {
return false;
}
$this -> aOptions['EXCEPTION'] = $mVal;
if (true === $mVal) {
set_exception_handler (array ($this, 'myExceptionHandler'));
} else {
restore_exception_handler ();
}
break;
case 'ENABLE' :
if (!array_key_exists ($mVal, $this -> aEnabled)) {
return false;
}
$this -> aEnabled[$mVal] = true;
break;
case 'DISABLE' :
if (!array_key_exists ($mVal, $this -> aEnabled)) {
return false;
}
$this -> aEnabled[$mVal] = false;
break;
default:
return false;
break;
}
return true;
}
/**
* public function __get ()
* allows some properties to be get
* @Param (string) sProp : name of the property
* @Return (boolean) false if failed, value of the property if succeeded
*/
public function __get ($sProp) {
if (false === array_key_exists ($sProp, $this -> aCanBeSet)) {
return false;
}
$sRealProp = $this -> aCanBeSet[$sProp];
return $this -> $sRealProp;
}
}
?>
Conclusion
Je mets ce code en expert (mon premier ;-) ) parce que je pense qu'il en a le niveau.
L'utilisation est relativement simple, mais il y a pas mal de possibilités (voir les 3 fichiers index.php en exemple).
Par contre, côté code, il fait appel à pas mal de notions que les débutants et même pas mal de codeurs confirmés auront du mal à décrypter (je ne parle pas des pros, et il y en a sur ce site!).
Gestion d'erreurs, gestion d'exceptions, parsing XML poussé, système de templates...
Voilà,
enjoy :-)
Historique
- 13 juin 2006 13:47:15 :
- Petite modif mineure, un oubli.
- 14 juin 2006 11:06:23 :
- Changement de l'attribution de l'id pour SHOW SOURCE et SHOW CONTEXT, ajout d'un uniqid().
- 14 juin 2006 11:54:38 :
- ajouts dans la description.
- 14 juin 2006 17:27:52 :
- Localisation en anglais et ajout d'une doc plus conséquente.
- 14 juin 2006 18:18:22 :
- Ajout d'une méthode __get ().
- 15 juin 2006 11:14:24 :
- Modification sur checkCode () : on peut désormais passer un fichier en paramètre. De plus, dans ce cas, le debugger retourne le bon nom de fichier, et la bonne ligne d'erreur
- 15 juin 2006 11:33:21 :
- Oubli...
- 10 août 2006 17:38:31 :
- Modification pour permettre à cette classe d'être utilisée n'importe où dans l'architecture d'un site. On peut instancier la classe avec un tableau contenant 4 options pour les chemins. voir le fichier index.php à la racine de l'archive.
Si on ne passe pas ce tableau d'options, les valeurs sont mises par défaut (bref, ça fonctionne aussi comme avant).
- 14 août 2006 09:20:18 :
- Bugfixing
- 12 septembre 2006 13:42:21 :
- - modification de bugs mineurs
- ajout d'options pour permettre d'activer ou de désactiver la gestion d'un type d'erreur.
- 20 septembre 2006 16:20:33 :
- Bugfixing
- 21 septembre 2006 15:21:39 :
- Ajout du contexte
- 21 septembre 2006 17:31:49 :
- Modification des templates pour les logs
- 26 septembre 2006 18:06:18 :
- ...
- 28 septembre 2006 18:21:22 :
- Bugfixing, grâce à Sven Drieling, qui a trouvé un bug sur Unix.
Modification and odebugger::createLog () :
$aTemp = explode ('\\', $sTemp);
a été remplacé par
$aTemp = preg_split('#/|\\\\#', $sTemp);
- 17 novembre 2006 11:02:57 :
- Ajout d'une option LOGUNIQUE
Ajout d'une doc plus claire et plus complète en français, au format WORD
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Gestion des erreurs [ par Linkman ]
Bonjour,Savez-vous comment construire une bonne gestion des erreurs comme par exemple celle de phpbb qui est capable de dire par exemple si il y a tro
gestion personalisé des erreurs( pb : E_PARSE [ par gogosnake ]
bonjour a tous,j'ai cree un script avec "set_error_handler" me permetant de gerer les erreur php.Tous marche parfaitement exepté pour les "Parse error
Gestion des erreurs [ par aquouel ]
Bonjour tout le monde, j'ai un soucis pour retourner les erreurs sur la page de mon formulaire. Je m'explique: Page: formulaire.
impossible de sauvegarder les données (php et XML) [ par vacknov ]
Bonjour;J'ai le message d'erreur Fatal error: Call to a member function appendChild() on a non-object in C:\wamp\www\newsxml.php on line 30lorsque Je
Gérer erreurs dans un formulaire [ par chandler8692 ]
Bonjour. Je sui noob en PHP; Je m'y suis mis il y a trois jours car j'ai un projet à faire pour mon école. Je crée un sondage en php dont les premier
recuperer valeur d'une page [ par gazalii ]
Bonjour,j'ai besoin de recuperer un resultat d'une page qui me renvoie un flux xmlje m'explique , j'ai une page que je dois appeler apartir d'une fonc
probleme pour traité XML [ par Renus02 ]
Bonjour,mon probleme est le suivant,j'ai un formulaire qui envoi des données (methode POST) a un partenaire,en retour il m'affiche des données au fort
Problème de SESSION [ par m2rtech ]
Salut à tous Comment affecter à une variable SESSION une valeur provenant d'un formulaire ussu de la MEME page ?<form name="formulaire" action="for
LIRE DES BALISES XML [ par loupile ]
bonjour, je suis en PHP5 j'arrive bien a lire le contenu de balise simple dans un fichier xml mais je n'arrive pas a lire des balises aves des caracte
DOMDocument - personnaliser ? [ par tipat10 ]
Bonjour,Je souhaite "personnalier" les fonctions de DOMDocument.J'ai donc créer ma propre classe :class xml extends DOMDocument{ <font face="Couri
|
Derniers Blogs
IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc REACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITERREACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITER par Groc
Une mauvaise utilisation de rx lors de l'écriture d'une couche d'accès à des services peut conduire à des cas embarassants avec des erreurs mal gérées, des appels qui ne partent lorsqu'ils le devraient, et même des résultats incorrects . le tout nuis...
Cliquez pour lire la suite de l'article par Groc SHAREPOINT BLOG SITE, PROBLèME D'ARCHIVESSHAREPOINT BLOG SITE, PROBLèME D'ARCHIVES par junarnoalg
Dernièrement, nous avons migré le site
myTIC
vers un nouveau serveur SharePoint 2010. Dans les contenus que nous vouloins récupérer, nous avions un certain nombre de blogs.
Nous avons utilisé les commandes Power...
Cliquez pour lire la suite de l'article par junarnoalg
Logiciels
sDEVIS-FACTURES vlPRO (8.1.0.3)SDEVIS-FACTURES VLPRO (8.1.0.3)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO 974 Application Server (12.2.4.6)974 APPLICATION SERVER (12.2.4.6)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP
|