This article mainly introduces a PHP error and exception handling class with a very good display effect. The code is clear and powerful. For more information, see the following ,:
II. Implementation Code
The Code is as follows:
// Custom exception Functions
Set_exception_handler ('handle _ exception ');
// Custom error functions
Set_error_handler ('handle _ error ');
/**
* Exception Handling
*
* @ Param mixed $ exception object
* @ Author blog.snsgou.com
*/
Function handle_exception ($ exception ){
Error: exceptionError ($ exception );
}
/**
* Handle errors
*
* @ Param string $ errNo error code
* @ Param string $ errStr error message
* @ Param string $ errFile error file
* @ Param string $ errLine error line
* @ Author blog.snsgou.com
*/
Function handle_error ($ errNo, $ errStr, $ errFile, $ errLine ){
If ($ errNo ){
Error: systemError ($ errStr, false, true, false );
}
}
/**
* System error handling
*
* @ Author blog.snsgou.com
*/
Class Error {
Public static function systemError ($ message, $ show = true, $ save = true, $ halt = true ){
List ($ showTrace, $ logTrace) = self: debugBacktrace ();
If ($ save ){
$ MessageSave =''. $ Message .'
PHP:'. $ LogTrace;
Self: writeErrorLog ($ messageSave );
}
If ($ show ){
Self: showError ('system ',"
$ Message", $ ShowTrace, 0 );
}
If ($ halt ){
Exit ();
} Else {
Return $ message;
}
}
/**
* Code Execution backtracking Information
*
* @ Static
* @ Access public
*/
Public static function debugBacktrace (){
$ SkipFunc [] = 'error-> debugBacktrace ';
$ Show = $ log = '';
$ DebugBacktrace = debug_backtrace ();
Ksort ($ debugBacktrace );
Foreach ($ debugBacktrace as $ k => $ error ){
If (! Isset ($ error ['file']) {
// Use the reflection API to obtain the file and number of rows where the method/function is located
Try {
If (isset ($ error ['class']) {
$ Reflection = new ReflectionMethod ($ error ['class'], $ error ['function']);
} Else {
$ Reflection = new ReflectionFunction ($ error ['function']);
}
$ Error ['file'] = $ reflection-> getFileName ();
$ Error ['line'] = $ reflection-> getStartLine ();
} Catch (Exception $ e ){
Continue;
}
}
$ File = str_replace (SITE_PATH, '', $ error ['file']);
$ Func = isset ($ error ['class'])? $ Error ['class']: '';
$ Func. = isset ($ error ['type'])? $ Error ['type']: '';
$ Func. = isset ($ error ['function'])? $ Error ['function']: '';
If (in_array ($ func, $ skipFunc )){
Break;
}
$ Error ['line'] = sprintf ('% 04d', $ error ['line']);
$ Show. ='
[Line: '. $ error ['line'].'] '. $ file.' ('. $ func .')';
$ Log. =! Empty ($ log )? '-> ':'';
$ Log. = $ file. ':'. $ error ['line'];
}
Return array ($ show, $ log );
}
/**
* Exception Handling
*
* @ Static
* @ Access public
* @ Param mixed $ exception
*/
Public static function exceptionError ($ exception ){
If ($ exception instanceof DbException ){
$ Type = 'db ';
} Else {
$ Type = 'system ';
}
If ($ type = 'db '){
$ ErrorMsg = '('. $ exception-> getCode ().')';
$ ErrorMsg. = self: sqlClear ($ exception-> getMessage (), $ exception-> getDbConfig ());
If ($ exception-> getSql ()){
$ ErrorMsg. ='
';
$ ErrorMsg. = self: sqlClear ($ exception-> getSql (), $ exception-> getDbConfig ());
$ ErrorMsg. ='
';
}
} Else {
$ ErrorMsg = $ exception-> getMessage ();
}
$ Trace = $ exception-> getTrace ();
Krsort ($ trace );
$ Trace [] = array ('file' => $ exception-> getFile (), 'line' => $ exception-> getLine (), 'function' => 'Break ');
$ PhpMsg = array ();
Foreach ($ trace as $ error ){
If (! Empty ($ error ['function']) {
$ Fun = '';
If (! Empty ($ error ['class']) {
$ Fun. = $ error ['class']. $ error ['type'];
}
$ Fun. = $ error ['function']. '(';
If (! Empty ($ error ['args']) {
$ Mark = '';
Foreach ($ error ['args'] as $ arg ){
$ Fun. = $ mark;
If (is_array ($ arg )){
$ Fun. = 'array ';
} Elseif (is_bool ($ arg )){
$ Fun. = $ arg? 'True': 'false ';
} Elseif (is_int ($ arg )){
$ Fun. = (defined ('site _ debug') & SITE_DEBUG )? $ Arg: '% d ';
} Elseif (is_float ($ arg )){
$ Fun. = (defined ('site _ debug') & SITE_DEBUG )? $ Arg: '% F ';
} Else {
$ Fun. = (defined ('site _ debug') & SITE_DEBUG )? '\ ''. Htmlspecialchars (substr (self: clear ($ arg), 0, 10). (strlen ($ arg)> 10? '...': ''). '\'':' % S ';
}
$ Mark = ',';
}
}
$ Fun. = ')';
$ Error ['function'] = $ fun;
}
If (! Isset ($ error ['line']) {
Continue;
}
$ PhpMsg [] = array ('file' => str_replace (array (SITE_PATH, '\'), array ('','/'), $ error ['file']), 'line' => $ error ['line'], 'function' => $ error ['function']);
}
Self: showError ($ type, $ errorMsg, $ phpMsg );
Exit ();
}
/**
* Record error logs
*
* @ Static
* @ Access public
* @ Param string $ message
*/
Public static function writeErrorLog ($ message ){
Return false; // do not write data temporarily
$ Message = self: clear ($ message );
$ Time = time ();
$ File = LOG_PATH. '/'. date ('Y. m. D'). '_ errorlog. php ';
$ Hash = md5 ($ message );
$ UserId = 0;
$ Ip = get_client_ip ();
$ User ='User:UserId = '. intval ($ userId).'; IP = '. $ ip.'; RIP: '. $ _ SERVER ['remote _ ADDR'];
$ Uri = 'request: '. htmlspecialchars (self: clear ($ _ SERVER ['request _ URI']);
$ Message =" \ T {$ time} \ t $ message \ t $ hash \ t $ user $ uri \ n ";
// Determine whether the $ message has been recorded in the time interval $ maxtime. If yes, no record is required.
If (is_file ($ file )){
$ Fp = @ fopen ($ file, 'rb ');
$ Lastlen = 50000; // read the last $ lastlen length bytes.
$ Maxtime = 60*10; // interval: 10 minutes
$ Offset = filesize ($ file)-$ lastlen;
If ($ offset> 0 ){
Fseek ($ fp, $ offset );
}
If ($ data = fread ($ fp, $ lastlen )){
$ Array = explode ("\ n", $ data );
If (is_array ($ array ))
Foreach ($ array as $ key => $ val ){
$ Row = explode ("\ t", $ val );
If ($ row [0]! =' '){
Continue;
}
If ($ row [3] === hash & ($ row [1]> $ time-$ maxtime )){
Return;
}
}
}
}
Error_log ($ message, 3, $ file );
}
/**
* Clear some characters in text
*
* @ Param string $ message
*/
Public static function clear ($ message ){
Return str_replace (array ("\ t", "\ r", "\ n"), "", $ message );
}
/**
* SQL statement character cleanup
*
* @ Static
* @ Access public
* @ Param string $ message
* @ Param string $ dbConfig
*/
Public static function sqlClear ($ message, $ dbConfig ){
$ Message = self: clear ($ message );
If (! (Defined ('site _ debug') & SITE_DEBUG )){
$ Message = str_replace ($ dbConfig ['database'], '***', $ message );
// $ Message = str_replace ($ dbConfig ['prefix'], '***', $ message );
$ Message = str_replace (C ('db _ prefix'), '***', $ message );
}
$ Message = htmlspecialchars ($ message );
Return $ message;
}
/**
* Display Error
*
* @ Static
* @ Access public
* @ Param string $ type Error type db, system
* @ Param string $ errorMsg
* @ Param string $ phpMsg
*/
Public static function showError ($ type, $ errorMsg, $ phpMsg = ''){
Global $ _ G;
$ ErrorMsg = str_replace (SITE_PATH, '', $ errorMsg );
Ob_end_clean ();
$ Host = $ _ SERVER ['HTTP _ host'];
$ Title = $ type = 'db '? 'Database': 'system ';
Echo <
$ Host-$ title Error
$ Title Error
$ ErrorMsg
EOT;
If (! Empty ($ phpMsg )){
Echo'
';
Echo'
PHP Debug
';
Echo'
';If (is_array ($ phpMsg )){Echo'
No. |
File |
Line |
Code |
';Foreach ($ phpMsg as $ k => $ msg ){$ K ++;Echo'
';Echo'
'. $ K .' | ';Echo'
'. $ Msg ['file'].' | ';Echo'
'. $ Msg ['line'].' | ';Echo'
'. $ Msg ['function'].' | ';Echo'
';}} Else {Echo'
|
';}Echo'
';
}
Echo <
EOT;
Exit ();
}
}
/**
* DB exception class
*
* @ Author blog.snsgou.com
*/
Class DbException extends Exception {
Protected $ SQL;
Protected $ dbConfig; // Current Database Configuration Information
Public function _ construct ($ message, $ code = 0, $ SQL = '', $ dbConfig = array ()){
$ This-> SQL = $ SQL;
$ This-> dbConfig = $ dbConfig;
Parent: :__ construct ($ message, $ code );
}
Public function getSql (){
Return $ this-> SQL;
}
Public function getDbConfig (){
Return $ this-> dbConfig;
}
}