begin process at 2012 05 27 17:59:12
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Divers

 > [PHP5] PHP DEBUGGER ET HELPER

[PHP5] PHP DEBUGGER ET HELPER


 Information sur la source

Note :
9,9 / 10 - par 10 personnes
9,90 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Divers Classé sous :gestion, erreurs, exceptions, debugger, xml Niveau :Expert Date de création :13/06/2006 Date de mise à jour :17/11/2006 11:02:56 Vu / téléchargé :8 136 / 488

Auteur : malalam

Ecrire un message privé
Site perso
Commentaire sur cette source (50)
Ajouter un commentaire et/ou une note

 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 (
  • '&nbsp;' => '&#160',
  • '>' => '&gt;',
  • '<' => '&lt;',
  • '&' => '&amp;'
  • );
  • /**
  • * 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 (
		'&nbsp;' => '&#160',
		'>' => '&gt;',
		'<' => '&lt;',
		'&' => '&amp;'
		);

	/**
	* 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 :-)

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 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

Source avec Zip ASTUCES/HACK PHP
SQUELETTE DE GESTION DES DROITS
[PHP 5.1] CLASS STRING : NOUVEL EXEMPLE SUR LA SPL
Source avec Zip Source avec une capture [PHP 5.1] PHOTOPHOP (PHPDRAW 2)
Source avec Zip Source avec une capture [PHP5.1] O-LOC : CLASSE ET BACKOFFICE D'INTERNATIONALISATION

 Sources de la même categorie

Source avec une capture MODULE JOOMLA 1.5 NOW LISTENING par Alcantornet
Source avec Zip Source avec une capture UPLOAD CENTER par basssem81
Source avec Zip COMPTEUR DE CLIQUE PHP AVEC JQUERY par devgoneti
Source avec Zip LIVRE D'OR SIMPLE (POUR DÉBUTANT) par devgoneti
Source avec Zip SCRIPT TRAVAUX POUR VOTRE SITE par FleuryK

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture VOIR QUI VISITE VOTRE SITE par Dariumis
Source avec Zip Source avec une capture GESTION DE SCOLARITÉ [PHP] ET [MYSQL] par ayoubshadow
GESTION D'ERREURS par Luzy
CLASSE DE CONFIGURATION POUR LA GESTION D'ERREUR par FredT
XML AVEC SIMPLE XML par GillesWebmaster

Commentaires et avis

Commentaire de Teclis01 le 13/06/2006 13:51:10

Que dire... Encore un outils plutot sympa que nous offre malalam que j'ai pu essayer (en tant que utilisateur) et que je trouve vraiment bien bien...
seul regret qu'il ait pas imposer un typage de variable !!! llooll ok ok je sort ^^
Franchement essayez ca vaut le detour !
(Vivement la gestion des exceptions ;o) )
et comme j ai misé cher sur cette source je met 10 :Op
non je met 10 car:
Originalité 5/5
Propreté 4.5/5 (j'y tiens a mon m_ pour les données membres ;o))
Difficulté 5/5
Malalam c'est mon namoureux ^^ 5/5

Commentaire de malalam le 13/06/2006 14:03:39 administrateur CS

Lol, marciii... ;-)

Commentaire de kankrelune le 13/06/2006 16:40:03

Miam... je regarderais le code quand j'aurais le temps et je ferais le retour dans la foulée mais ça a l'air vraiment bueno tout ça... .. . ;o)

@ tchaOo°

Commentaire de J_G le 13/06/2006 16:47:06

Ah oui... oui oui !

C'est bien !

Tu t'es donné du mal même pour traduire toutes les erreurs dans ton fichier errors.xml...

Pareil : 9.5/10 car j'ai du passé la fonction __set de private à public pour pouvoir utiliser la classe (? PHP 5.0.4 ?)

A+

Commentaire de malalam le 13/06/2006 16:58:52 administrateur CS

J_G => merci :-)
Pour __set () je ne sais pas. Suis en 5.1.1. ET l'exemple sur la doc le met en private, donc j'ai suivi. Et comme ça marchait, je ne me suis pas posé de question lol. La doc ne précise pas de version PHP pour ça. (ou je n'ai pas trouvé).

Je n'ai pas traduit toutes les erreurs...juste celles que j'ai trouvé sur Nexen (auquel Kankrelune est habitué d'ailleurs...j'ai pu voir... ;-) ). Mais j'en ajouterai...et tout le monde peut en ajouter à vrai dire :-)

Kankrelune => merci aussi :-)

Commentaire de kankrelune le 13/06/2006 17:08:19

Petite remarque mineur... il faudrait mettre un index.html vide et éventuellement un .htaccess dans le répertoire log... .. .

Sinon bah ouais... nexen et php.net son mes sites de chevet... lol... et la doc php aussi... avec la mémoire que j'ais c'est bien pratique... s'appel comment cette fonction déja... muarf... lOo°oOl... .. . ;)

@ tchaOo°

Commentaire de malalam le 13/06/2006 17:37:59 administrateur CS

Kankrelune => ouais, mais comme je l'ai dit, ce package n'est pas destiné à se retrouver sur un environnement de prod, mais uniquement de dév.
Bon ok, je suis dans le métier et donc je développe comme un riche : j'ai un serveur de prod ET un serveur de dév...interne, donc innaccessible de l'extérieur ;-) Bref le problème ne se pose pas pour moi.
Ceci dit, oui, pourquoi pas, chacun configurera son serveur à sa sauce pour protéger les répertoires.

Commentaire de audayls le 13/06/2006 21:39:42

Bonsoir,
Je trouve que ce script est une très bonne idée pour nous aider à comprendre les erreurs (et donc à les résoudre plus facilement).
Petit bug sur les fonctions "SHOW CONTEXT" et "SHOW SOURCE" (enfin en fait le bug c'est peut-être que dans ma tête mais lorsque je clique sur le "SHOW SOURCE" du bas c'est toujours le premier qui s'ouvre...
Une petite fonction interressante que tu pourrais rajouter c'est l'envoie d'un e-mail lorsqu'une erreur est trouvée comme çà le Webmaster pourrait être prévenu encore plus vite.
Par contre je ne connais pas beaucoup les classes mais il n'y aurait pas un moyen de faire fonctionner cette classe avec PHP 4 (je ne pense pas mais bon autant demander pour être sur :P)

Commentaire de FhX le 13/06/2006 22:54:24

php4 ? Ouh la non c'est impossible rien qu'avec __set() par exemple.

Ca m'oblige quand même à regarder le code de Mala... arf arf arf :p

Commentaire de malalam le 14/06/2006 08:33:28 administrateur CS

Audalys => déjà, merci :-) Ensuite, pour le problème que tu soulèves sur les SHOW SOURCE et SHOW CONTEXT, j'aurais besoin d'une petite info : sur quel navigateur as tu fait tourné le code ? En fait, le principe est simple. Quand je génère l'affichage, je fous des id sur des span (voui, ce sont des span). 2 problèmes arrivent alors : je me rends compte, à priori (mais je vérifierai ça tt à l'heure), qu'il y a un risque d'avoir 2 id identiques (pas bien ça) si on instancie 2 debugger. Ensuite, que j'ai -mea culpa- complètement oublié de tester le code sous IE. Et que la gestion des blocks d'IE peut peut-être poser problème. Bref, je vais voir...
Pour PHP4 : ça va être chaud : déjà, sur les exceptions, c'est mort. Ensuite, je pense que j'utilise beaucoup de fonctions spéciales PHP5. Le __set(), en effet, risque de poser problème...va falloir contourner. Mais bon...j'y réfléchirai. Ce qui est sûr, c'est qu'il faut réécrire la classe complètement. Il y a __set (), DOMDocument PHP5, et je ne suis pas sûr pour error_set_handler(), à dire vrai...

FhX => mate donc ;-)

Je compte sérieusement l'améliorer, ce principe me plait lol. Donc si vous avez des idées, je suis preneur. De la même manière, je lance un appel : si certains relèvent des erreurs PHP que je n'ai pas mis dans mon fichier errors.xml, bref, si vous trouvez des erreurs que je ne traduis pas, et pour lesquelles je ne donne pas de suggestion, ce serait sympa de m'en faire part histoire que je les ajoute.

Vlà :-)

Commentaire de malalam le 14/06/2006 11:09:31 administrateur CS

Audalys => bug non reproduit. Mais j'ai modifié un peu l'attribution de l'id. Je passe par un uniqid() en plus, ce qui devrait déjà éviter un chevauchement de deux id si on instancie 2 fois la classe dans la même page.

Commentaire de kankrelune le 14/06/2006 11:23:52

[quote]et je ne suis pas sûr pour error_set_handler(), à dire vrai[/quote]

Si si ça marche très bien sous php4... j'ais une class de gestion des erreurs en php4 qui ressemble (de loin) à la tienne... en bien moins évoluée... .. . ;o)

Pour le problème d'instanciation pourquoi ne pas faire que getInstance()... .. ?

moi c'est ce que je fais (pour la plupart de mes class d'ailleurs) ce qui permet d'avoir toutes les erreurs dans le même object quel que soit le nombre de fois ou tu l'appel... .. .

@ tchaOo°

Commentaire de kankrelune le 14/06/2006 11:27:13

[quote]
j'ai un serveur de prod ET un serveur de dév...interne, donc innaccessible de l'extérieur ;-)[/quote]

foiré va... .. . ;o)

[quote]ouais, mais comme je l'ai dit, ce package n'est pas destiné à se retrouver sur un environnement de prod, mais uniquement de dév.[/quote]

Non au contraire je pense qu'il peut être interessant de l'intégrer dans un site sous forme de débug mode... moi c'est ce que je fais sur certains site... non activé il n'affiche pas les erreurs et éventuellement les log... activé il affiche les erreurs mais uniquement pour les admin... .. . ;o)

@ tchaOo°

Commentaire de malalam le 14/06/2006 11:49:55 administrateur CS

"Si si ça marche très bien sous php4... j'ais une class de gestion des erreurs en php4 qui ressemble (de loin) à la tienne... en bien moins évoluée... .. . ;o)"

=> bon, alors reste à vérifier chaque fonction que j'utilise et à modifier celles qui ne sont dispo que sous PHP5...vais y réflêchir :-) Reste DOM à passer en DOM XML...mais là, y a peu de changement à priori. Et un problème majeur pour moi : je n'ai plus aucun serveur en PHP4 lol...donc pour tester, dur dur! Le __set () ne pose pas de problème véritable. On ne passe plus par __set(), et basta. De ttes façons, y a pas de notion public/protected/private en PHP4 alors...

"Pour le problème d'instanciation pourquoi ne pas faire que getInstance()... .. ? "
Y a pas de problème ;-) A priori. Juste éventuellement un chevauchement d'id qui est résolu via l'ajout d'un uniqid().
Maintenant...je peux effecticement implémenter une méthode singleton. Mais, il faut d'abord répondre à ces 3 questions :
- est-il utile de n'autoriser qu'une seule instance de cette classe sur un script ?
- cela peut-il poser un problème de créer plusieurs instances de cette classe sur un seul script ?
- pourrait-il y avoir une utilité à créer plusieurs instances de cette classe sur un seul script...;-) ?
Chais pas encore, je dois y réflêchir.

"foiré va... .. . ;o)"
=> héhé ;-) C'est l'avantage d'être responsable de dév dans une boîte ;-)

Pour le reste, ouais, pourquoi pas en effet. Généralement, je pars du principe qu'en prod, il n'y a aucune erreur de script, lol, mais uniquement des erreurs d'utilisation. Donc, je trace et logge les actions de mes utilisateurs uniquement ;-)

Commentaire de kankrelune le 14/06/2006 13:51:21

Franchement un portage sous php4 ça serait top mais je pense que c'est beaucoups de boulot pour pas grand chose... ça serait bien pour les utilisateurs n'ayant pas php5 mais d'une part tu vas te faire chier (notament au niveau DOM), d'autre part ceux qui ne sont pas sous php5 finiront bien par y passer... après je dis ça... hormis en local je suis encore sur php4... .. .

Pour l'instanciation unique perso je trouve ça utile (avis perso ça n'engage donc que moi)... comme ça la class peut être utilisée comme "gestionnaire" d'exception... enfin c'est pas vraiment le mot mais je pense que tu m'aura compris... et notament dans d'autres class... le singletion devient interessant car tu est succeptible d'instancier la class plusieurs fois... cependant mon raisonement est issu de php4 avec les exeptions de php5 c'est vrai que c'est peut être pas très utile... .. .

[quote]héhé ;-) C'est l'avantage d'être responsable de dév dans une boîte ;-)[/quote]
Foiré va... lOo°oOl... .. .

[quote]Pour le reste, ouais, pourquoi pas en effet. Généralement, je pars du principe qu'en prod, il n'y a aucune erreur de script, lol, mais uniquement des erreurs d'utilisation. Donc, je trace et logge les actions de mes utilisateurs uniquement[/quote]

Tout à fait d'accord sur un site """pro""" (note les guillements)... mais sur un site amateur cela peut être différent et un gestionnaire de débugage peut devenir interessant... de toute façon chacun peu l'adapter à sa sauce... .. . ;o)

@ tchaOo°

Commentaire de TheSin le 14/06/2006 14:01:20

Génial ta classe xD
Dommage que je bosse pas en PHP5 ^^
Au passage, je rectifie une erreur dans les commentaires, c'est pas error_set_handler(), mais set_error_handler()  ;-)
10/10 ;-)

Commentaire de malalam le 14/06/2006 14:31:44 administrateur CS

Merci TheSin :-)
Je corrigerai le mauvais commentaire lol désolé.

je vais faire une mise à jour cet apm ou demain : j'ai localisé le code en anglais aussi (valeur par défaut d'ailleurs).

Commentaire de FhX le 14/06/2006 20:33:11

Moi j'ai ca à te soumettre :)

La, ta classe actuelle ne te permet de récupérer les erreurs que d'une seule langue. Mais imagions que je te demande de me faire une gestion d'erreur comme ceci :

Erreur : variable indéfini $xxxxxxx .....

---------------

Error : undefined variable $xxxxxxx .....


Avec ta classe actuelle, je crois bien que tu ne peux pas le faire étant donné que tu demandes la langue à l'instanciation !
Chui sur qu'en faisant 2-3 modifs y'aurait moyen de trouver ca. (jvais essayer de m'y pencher)

Commentaire de guill76 le 14/06/2006 23:33:15

Super fort ton code, mais le problème, c'est qu'on aime bien savoir quand on rencontre un bug, à quelle endroit l'erreur s'est produite et non l'endroit où elle est détectée:
Dans ton fichier test.php que tu check dans index3.php, tu récupères des erreurs (normal),mais le fichier ou les erreurs sont signalées est le fichier de ta classe et non test.php.
Ce qui est un peu moins pratique que le debug php sur ce point là en tous cas.

Commentaire de malalam le 15/06/2006 06:43:49 administrateur CS

FhX => j'étais sûr qu'un emmerdeur me demanderait ça... ;-)
Le problème ne vient pas de la langue, pas réellement...mais plutôt de savoir où remplacer la variable! Et combien de variables je vais avoir à afficher. J'y ai pensé, en fait...! Et je vais continué à y penser parce que, ouais, ce serait une très bnonne idée :-)

Guil76 => oui, je sais, à vrai dire c'est la méthode que j'utilise qui fait ça : j'utilise la fonction assert () pour analyser le code dans ces cas là (puisque dans index3, j'analyse un code se trouvant dans un autre fichier, pas le code qui est exécuté par le script courant), et elle fait une sorte d'eval du texte qu'on lui donne. Mais, comme c'est du texte, qu'elle attend, je récupère ce texte dans index3, en lisant le fichier test.php. Du coup, l'erreur est détectée dans index3.
Je n'ai pas encore trouvé de moyen "simple et élégant" de corriger ça. Mais j'ai un moyen "bourrin et moche" par contre, lol. Je le mettrai peut-être en attendant :-) Parce que oui tu as raison, du coup, sur la méthode odebugger::checkCode(), ma classe perd de son intérêt.

Commentaire de malalam le 15/06/2006 06:46:54 administrateur CS

FhX => Ah naaaan, nan j'avais pas pigé ta proposition! Du tout!! Lol, on reprend : ah ben, je n'y avais pas du tout pensé à ça. Pourquoi pas en effet. Mais tu as raison, je ne peux pas en l'état actuel de ma classe...mais heu...c'est faisable, en ajoutant une option de langue :-) Je m'y penche cet apm :-) Merci!

Commentaire de guill76 le 15/06/2006 07:30:02

Et pour les include, require même problème je suppose, tu pourrais rendre la métohde check récursive, et récupérer un tableau indiquant la ligne d'erreur et le fichier ou l'erreur se trouve.

Commentaire de malalam le 15/06/2006 08:12:55 administrateur CS

Nan, en fait, le principe est simple, je suis bête.
assert prend une chaîne. Cette chaîne, dans index3.php,  je la récupère à partir d'un file_get_contents ('test.php').
1 - mon gestionnaire ne sait pas de quel fichier provient ces lignes. Résolution : j'uatoris à passer une chaîne, OU un fichier. Dans ma méthode, je teste si c'est un fichier existant, ou une chaîne. Si c'est un fichier, je le lis, et je fais mon assert() dessus.
2 - il indique, pour cet exemple, une erreur à la ligne 1. Ce qui est tout à fait juste! Parce que le fichier test.php ne contient que 3 lignes, dont <?php et ?>. Etant donné que je vire les balises ouvrantes et fermantes de php pour ne pas avoir d'erreur, il ne retrouve qu'une ligne. Donc, pour indiquer le numéro d'erreur réel, il suffit que j'ajoute 1. Dans la plupart des cas.

Bref, je ferai cette correction tout à l'heure :-)

Commentaire de malalam le 15/06/2006 11:15:54 administrateur CS

Guill76 => fait, çe marche maintenant mieux :-)

Commentaire de kankrelune le 15/06/2006 12:05:02

Je sais pas si j'ais pigé ce que veux Guill76 (que de toute façon tu semble avoir résolu) mais voila comment je fais... j'ais une méthode backtrace() dans ma class dedans je récupère le contexte de débogage grace à debug_backtrace() je parcour le tableau à partir du 2ème enregistrement si je me souvient bien (pour virer l'appel de la methode backtrace et de la methode qui consigne l'erreur) puis j'assemble les infos du tableau jusqu'a ce que je tombe sur un include, require ou que j'atteigne un certain niveau d'imbrication...

Ca permet en plus de savoir dans quel fichier et à quelle ligne se trouve l'erreur (que donne php à la consignation) de savoir quelle fonction,méthode à générée l'erreur s'il cette dernière à été elle même appelée par une fonction/méthode, etc... .. .

ce qui donne par exemple...

Warning bla bla à la ligne XX du fichier pwet.php
appelée par $monObj->methode() dans pwet.php ligne XX
appelée par fonction() dans plop.php ligne XX

@ tchaOo°

Commentaire de malalam le 15/06/2006 12:10:48 administrateur CS

Ouais, j'y ai pensé, mais le problème c'est que le debug_backtrace () est gros...vu qu'il contient tout le contexte. Y compris ma classe, quoi.
Ceci dit, c'est une bonne idée, je cherchge justement à exploiter ces fonctions :-) Au mieux, je veux dire. Ton truc a l'air pas mal du tout.

Commentaire de FhX le 15/06/2006 21:58:53

Moi j'y comprend rien...

C'est vrai ca, pourquoi maintenant les gens font des codes qu'on comprend jamais !!!


Olé, c'est vrai quoi :p Rien que ca : return $oLevel -> nextSibling -> nextSibling -> nodeValue;
De la récursivité dans les propriétés de classes !! Mais où va t'on !


J'ai essayé de trouver des erreurs dans ta classe... j'en vois aucune.
Ah si, peut être le fait de pas pouvoir l'étendre si un jour jveux faire mumuse avec :p Comment ca je dis des conneries .... ;)

Commentaire de malalam le 15/06/2006 22:38:11 administrateur CS

Eh beh, si le grand gourou de la POO PHP5 ne trouve pas d'erreur...suis flatté ;-)
MAIS...je code si bordélique que tu piges rien, lol? :-(
Nan bon...faut être un peu habitué à XPath en fait...et à DOM en général, du coup. Ca aide à piger les lignes aussi débiles que :
$oLabel -> nextSibling -> nextSibling -> nextSibling -> nextSibling -> nodeValue;
Horrible lol, suis bien d'accord. Et je PENSE que je peux optimiser  ça, mais j'ai un peu de mal avec XPath version PHP en fait...je m'en sors mieux avec une vrai XSL.

Et en fait, j'vais avoir besoin d'aide sans doute pour restructurer ça...enfin, des avis quoi ;-) La classe commence à être grosse et j'ai pas fini! Donc, j'veux scinder...bref, j'veux plusieurs classes!
Mais chais pas encore comment...

Commentaire de J_G le 16/06/2006 11:17:45

Salut,

Sous l'impulsion de ta question, j'ai mis les yeux un peux plus profond dans le code...

tu m'avais pas dis un jour que je ne mettais pas beaucoup d'espace dans mon code? Hum! Pis c'est pas trop commenté non-plus... Les comentaires de type DoxyGen ne font pas tout.

Bon voilà, c'est dit!


Sinon, pour faire du ménage dans ta classe... J'imagine assez bien la création d'une classe dont le but est uniquement d'interfacer avec tes fichiers log. Une autre qui s'occupe de la traduction avec errors.xml et types.xml. Une autre qui fait la moulinette des templates et donc affichage. Et enfin, une fois sortie tout ce bazard de ta classe, il ne reste plus que my???handler et quelques paramétrages dans la classe debbuger.

on à donc :
* LOG => I/O avec les fichiers date_id_error_log.xml
* TRANSLATE => O depuis les fichiers de traduction errors.xml et types.xml
* TEMPLATES => utilise les fichiers dans templates pour créer le code HTML qui sera affiché (donc templates utilise les deux précédant)
* DEBBUGER => Le pivot central


Voilà... Mais je ne suis pas un pro de la POO... A+

Commentaire de franco_se le 09/08/2006 14:06:56

juste pour info: il faut que le fichier a debugger soit dans le dossier debuggers ?
car j'ai essayé le code en mettant en tete d'un ficher
[code]
header ('Content-type: text/html; charset=utf-8');
require_once 'debugger/class/odebugger.cls.php';

$odebug = new odebugger ('FR'); // French localization
$odebug -> CSS = 'default'; // set the CSS
$odebug -> HTML = 'default'; // set the HTML template

[/code]

et il me renvoie des erreurs :
[quote]
Warning: scandir(xml) [function.scandir]: failed to open dir: Invalid argument in C:\Program Files\xampp\htdocs\ombres\includes\debugger\class\odebugger.cls.php on line 175

Warning: scandir() [function.scandir]: (errno 22): Invalid argument in C:\Program Files\xampp\htdocs\ombres\includes\debugger\class\odebugger.cls.php on line 175

Warning: in_array() [function.in-array]: Wrong datatype for second argument in C:\Program Files\xampp\htdocs\ombres\includes\debugger\class\odebugger.cls.php on line 176

Warning: DOMDocument::load() [function.load]: I/O warning : failed to load external entity "file:///C%3A/Program%20Files/xampp/htdocs/ombres/includes/xml/EN/errors.xml" in C:\Program Files\xampp\htdocs\ombres\includes\debugger\class\odebugger.cls.php on line 179

Warning: DOMDocument::load() [function.load]: I/O warning : failed to load external entity "file:///C%3A/Program%20Files/xampp/htdocs/ombres/includes/xml/EN/types.xml" in C:\Program Files\xampp\htdocs\ombres\includes\debugger\class\odebugger.cls.php on line 180
bla
bli
Fatal error: Exception thrown without a stack frame in Unknown on line 0
[/quote]

a moins que je l'ai mal installé ds ma page .......

Commentaire de FhX le 09/08/2006 14:53:24

t'as pas PHP5... !

Commentaire de franco_se le 09/08/2006 16:22:10

pourtant, quand je vais sue les indexN.php d'exemple, ça marche tres bien !
comprend pas ...........

Commentaire de kankrelune le 09/08/2006 16:29:06

Ca vient pas de php 5 car si il était sous php 4 il aurait une parse error avec les exceptions... .. .

@ tchaOo°

Commentaire de malalam le 10/08/2006 09:04:14 administrateur CS

Hello,

Franco_se => ton problème est un peu de ma faute. Je n'ai pas mis en propriétés de la classe certais chemins, comme ceux des logs, du xml...

Je modifierai ceci, parce que bon...
En attendant, voici ce qui se passe:

tu dans un dossier www/monsite/
Moi, mes sites sont toujours avec cette structure :
www/monsite/fichiers php...
www/monsite/class/classes php
www/monsite/xml/fichiers xml
etc...
du coup, je m'attends à ce que les pages à debugger soient à la racine : www/monsite/fichier à debugger.php

et que ma classe soit instanciée ici.
Et ma classe va chercher, à partir de la page dans laquelle est elle instanciée, les répertoire /xml, /logs, /templates etc...
Donc, dans des répertoires situés à la racine : www/monsite/xml/

Bref, les scandir, du coup, ne trouvent pas ce qu'ils veulent, où ils le veulent.

La modif est relativement simple : ajouter une propriété de chemin global, et utiliser le setter pour la mettre à jour.
Et évidemment, changer chaque chemins pour y ajouter cette propriété (quand on chercher xml/, etc...)

Commentaire de franco_se le 10/08/2006 16:46:07

justement, c'est le pb que je pensais: le script cherche les dossiers ds la racine alors que le tout est ds un repertoire ....
le probleme est que je n'ai pas encore étudier le systeme des class ( oui, je sais, c'est tres utile ...). alors, je ne sais pas creer cette variable ( autant l'appeller ds une fonction en Global pas de pb ) .
j'ai essayé de creer une variable
# public $debugger_dir = $_SERVER['DOCUMENT_ROOT'] . "/includes/debugger/";
mais les variables $_SERVER posent probleme.....

Commentaire de malalam le 10/08/2006 17:08:12 administrateur CS

je n'ai franchement pas le temps en ce moment de retourner sur ce code...je le ferai, mais il faudra être patient.

Sinon, une explication rapide... :
donne moi la structure de ton application web, et dans quels fichiers (et où sont-ils dans ta structure) tu veux utiliser ma classe ?

Maintenant, oui, il reste $_SERVER : mais il faut retoucher de toutes manières la classe, et lui ajouter des propriétés pour le chemin des xml, logs, templates (en plus du reste). Et utiliser ces propriétés partout où elle va utiliser ces chemins. Evidemment.

Si tu patientes un peu, je le ferai...mais il faudsra patienter!

Commentaire de malalam le 10/08/2006 17:40:37 administrateur CS

Bon, j'ai pris 2mn pour regarder, et la modif était vraiment rapide.
C'est donc fait :-)
télécharge cette nouvelle version, et teste le nouveau fichier index.php à la racine de l'archive. Regarde comment j'instancie ma classe.
Regarde aussi le constructeur de la classe pour voir ce que j'ai ajouté.

Commentaire de kankrelune le 10/08/2006 17:41:06

Definis une constante par répertoire et ajoute les dans les méthodes de la class... .. .

@ tchaOo°

Commentaire de malalam le 10/08/2006 18:00:46 administrateur CS

C'est aussi une possibilité voui. Mais j'aime bien conserver mes variables dans mes classes. Donc, les instancier avec (ou utiliser des setter pour les variables pouvant être modifiées en cours de script).
Mais il est vrai que la config via constantes peut parfois être plus simple. On les fout dans un fichier de conf, qui est inclus partout, et le tour est joué. Mais on sort de la classe...donc, pour cette classe, je vais en rester à la méthode que je viens d'utiliser.

Commentaire de kankrelune le 10/08/2006 18:19:58

Je parlais pour franco_se qui pige pas grand chose au class... c'est le moyen le plus simple je pense... .. . ;o)

@ tchaOo°

Commentaire de franco_se le 10/08/2006 18:58:28

malalam , ton script est genial ! il releve meme des bugs sur lui-meme! :

  [DATE]   10-08-2006 18:49:53   [TYPE]   Alerte   [PHP_MESSAGE]  DOMDocument::save(C:/Program Files/xampp/htdocs/ombres/includes/debugger/C:/Program Files/xampp/htdocs/ombres/includes/debugger/logs/20060810_44db63b116e39_error_log.xml) [function.save]: failed to open stream: Invalid argument   [FILE]   C:\Program Files\xampp\htdocs\ombres\includes\debugger\class\odebugger.cls.php   [LINE]   547   [MEMORY]   n/a
[TRANSLATION]
[SUGGESTION]
SHOW CONTEXT n/a
SHOW SOURCE
<?php
            $sFile = $this -> sCurId.'_error_log.xml';
        }
/** ERROR AROUND THIS LINE => */         $this -> oXMLDOC -> save ($this -> sCurDir.$this -> sLogPath.'/'.$sFile);
    }

?>

Commentaire de malalam le 10/08/2006 20:22:22 administrateur CS

Lol, chais pas comment je dois prendre ça...ceci dit, je sais : avec ma version de php5 (la dernière), il relève un warning sur l'utilisation de date ().
Pas le temps de regarder ton erreur; je verrai ça plus tard. A 1ère vue, un oublie de test d'existence sur un fichier, visiblement.

Commentaire de malalam le 14/08/2006 09:21:13 administrateur CS

Ok j'ai corrigé ce petit bug aussi.

Commentaire de franco_se le 25/08/2006 21:42:23

que dire si ce n'est: du grand art! 10/10 :D

Commentaire de malalam le 26/08/2006 12:22:24 administrateur CS

Merci beaucoup Franco :-)

Commentaire de malalam le 21/09/2006 15:23:03 administrateur CS

Pour ceux que ça intéresse ;-) :
j'ai fait pas mal de modifications sur ce code ces derniers temps.
Entre autres choses :
- correction de quelques bugs
- ajout d'une option permettant de choisir quels types d'erreurs seront loggés ou non
- ajout du contexte! Là, c'est chaud... : le contexte sort bien. Attention, TOUT le contexte courant, objets, variables, etc...pratique pour débugger, moins pour lire...: le contexte peut-être très grand. C'est surtout génant lors de l'affichage des logs après coup (pas en mode REALTIME donc) : le tableau est immense. je cherche un workaround...Mais cela peut aussi être génant pour les fichiers qui peuvent rapidement être très gros selon la taille du contexte.
Bref...j'y réfléchis :-)

Commentaire de kankrelune le 21/09/2006 15:40:09

Ouep bonne idée la gestion du context... perso j'ais abandonné (trop fouilli) pour me pencher sur debug_backtrace()... mais ça peut servir... .. .

@ tchaOo°

Commentaire de malalam le 21/09/2006 17:30:36 administrateur CS

je poste encore une nouvelle version ou seuls les templates ont changé, pour l'affichage des logs en différé. Plus clair.
Ouais, le contexte, je tâche de ne pas afficher celui du debugger...mais tout le reste oui, évidemment, c'est nécessaire.
Donc, les POST, GET, COOKIES, SESSION, objets instanciés, variables, constantes...ça en fait du monde lol.

Commentaire de audayls le 21/09/2006 22:56:48

J'ai jamais autant reçu d'E-mail pour me prévenir des commentaires d'une source ! Mais franchement je les attends avec impatience car cette source est très utile et elle s'améliore sans cesse ! (Quand es ce que tu nous fais un Windows Malalam ! lol) Mais par contre sa m'énerve parce que j'arriverai peut être jamais à faire un code pareil - -' Ô jalousie quand tu nous tiens :-P

Commentaire de malalam le 22/09/2006 08:13:42 administrateur CS

Bah, merci Audayls :-)
Je ne pense pas développer un jour un OS en PHP (ou alors, je serai vraiment devenu TRES fort...genre Néo dans la matrice lol), mais par contre, je suis certain que ce code-ci te sera abordable dans quelques temps. Suffit d'attendre, de chercher, de progresser, et tu seras vite largement au même niveau, sans problème :-) Ce code n'est pas si complexe qu'il en a l'air. C'est juste que ma programmation est pompeuse lol, et fait comme si elle était complexe ;-)

 Ajouter un commentaire


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 ?&lt;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


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 2,246 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales