PHP Classes

File: class/odebugger.cls.php

Recommend this page to a friend!
  Classes of Johan Barbier   PHP Debugger and Helper   class/odebugger.cls.php   Download  
File: class/odebugger.cls.php
Role: Class source
Content type: text/plain
Description: Debugger class
Class: PHP Debugger and Helper
Log errors and check PHP code
Author: By
Last change: Modifications on checkCode()
Date: 17 years ago
Size: 18,899 bytes
 

Contents

Class file image Download
<?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 conatin 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 ); /** * 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) 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']" ); /** * 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}' ); /** * 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') { @error_reporting (0); $aLnDir = scandir ('xml'); if (in_array ($sLang, $aLnDir)) { $this -> sLang = $sLang; } $this -> oXMLERRORS = DOMDocument::load ('xml/'.$this -> sLang.'/errors.xml'); $this -> oXMLTYPES = DOMDocument::load ('xml/'.$this -> sLang.'/types.xml'); $this -> oXMLDOC = new DOMDocument ('1.0', 'utf-8'); $root = $this -> oXMLDOC -> createElement ('ERRORLOG'); $this -> oXMLROOT = $this -> oXMLDOC -> appendChild ($root); if (!is_dir ('logs')) { @mkdir ('logs', 0744); } $sTemp = dirname (__FILE__); $aTemp = explode ('\\', $sTemp); array_pop ($aTemp); $this -> sCurDir = implode ('/', $aTemp).'/'; $this -> sCurId = date ('Ymd').'_'.uniqid(); set_error_handler (array ($this, 'myErrorHandler')); set_exception_handler (array ($this, 'myExceptionHandler')); } /** * 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); } /** * 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; } } } /** * 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; } } } /** * public function myExceptionHandler () * the exception handler : builds the XML error log * @Param (object) e : the Exception object */ public function myExceptionHandler ($e) { $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; } $sVars = $e -> getTraceAsString (); $aTempArr = array ('TRANSLATION' => '', 'SUGGESTION' => ''); $this -> buildLog ($sType, $sErrStr, $sErrFile, $iErrLine, $aTempArr, $sVars); } /** * 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 */ public function myErrorHandler ($cErrno, $sErrStr, $sErrFile, $iErrLine, $mVars) { $aTempArr = $this -> checkErrorMessage ($sErrStr); $sType = $this -> checkTypeTrans ($cErrno); $sVars = 'n/a'; if (!is_null ($this -> sAssertion)) { $sErrFile = $this -> sAssertion; $this -> sAssertion = null; } $this -> buildLog ($sType, $sErrStr, $sErrFile, $iErrLine, $aTempArr, $sVars); } /** * 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, $sVars) { $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']); $aElem[] = $this -> oXMLDOC -> createElement ('CONTEXT', $sVars); $oSource = $this -> oXMLDOC -> createElement ('SOURCE'); $aSourceElem = array (); foreach ($this -> getLine ($sErrFile, $iErrLine) as $iLine => $sLine) { $sLine = utf8_encode ($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 */ public function loadXML ($sFile) { if (!file_exists ('logs/'.$sFile)) { return false; } $this -> oXMLDOC -> load ('logs/'.$sFile); } /** * 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 ('templates/'.$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 ('templates/'.$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 = 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; 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 = highlight_string ('<?php '."\r\n".$sValeur.'?>', true); } else { $sValeur = $nodeList -> item($i) -> nodeValue; } $sHtml = str_replace ($this -> aIndex[$i][1], $sValeur, $sHtml); } return $sHtml; } /** * public function saveToFile () * save the current log to a given file * @Param (string) sFile : name of the log file */ public function saveToFile ($sFile = null) { if ($sFile === null) { $sFile = $this -> sCurId.'_error_log.xml'; } $this -> oXMLDOC -> save ($this -> sCurDir.'logs/'.$sFile); } /** * 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; return true; break; case 'HTML' : if (!file_exists ('templates/'.$mVal.'.dat')) { return false; } $this -> sTemplateHTML = $mVal; return true; break; case 'HTMLLOG' : if (!file_exists ('templates/'.$mVal.'.dat')) { return false; } $this -> sTemplateHTMLLOG = $mVal; return true; break; case 'CSS' : if (!file_exists ('css/'.$mVal.'.dat')) { return false; } $this -> sTemplateCSS = $mVal; readfile ('css/'.$mVal.'.dat'); return true; break; case 'CSSLOG' : if (!file_exists ('css/'.$mVal.'.dat')) { return false; } $this -> sTemplateCSSLOG = $mVal; readfile ('css/'.$mVal.'.dat'); return true; break; case 'REALTIME' : if (!is_bool ($mVal)) { return false; } $this -> aOptions['REALTIME'] = $mVal; return true; break; case 'LOGFILE' : if (!is_bool ($mVal)) { return false; } $this -> aOptions['LOG_FILE'] = $mVal; return true; 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 (); } return true; 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 (); } return true; break; default: return false; } } /** * 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; } } ?>