debugbacktrace'; $show = $log = ''; $debugbacktrace = debug_backtrace(); ksort($debugbacktrace); foreach ($debugbacktrace as $k => $error) { if (!isset($error['file'])) { // 利用反射api来获取方法/函数所在的文件和行数 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 ); } /** * 异常处理 * * @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(); } /** * 记录错误日志 * * @static * @access public * @param string $message */ public static function writeerrorlog($message) { return false; // 暂时不写入 http://www.phprm.com $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 = {$time} $message $hash $user $uri ; // 判断该$message是否在时间间隔$maxtime内已记录过,有,则不用再记录了 if (is_file($file)) { $fp = @fopen($file, 'rb'); $lastlen = 50000; // 读取最后的 $lastlen 长度字节内容 $maxtime = 60 * 10; // 时间间隔:10分钟 $offset = filesize($file) - $lastlen; if ($offset > 0) { fseek($fp, $offset); } if ($data = fread($fp, $lastlen)) { $array = explode( , $data); if (is_array($array)) foreach ($array as $key => $val) { $row = explode( , $val); if ($row[0] != '') { continue; } if ($row[3] == $hash && ($row[1] > $time - $maxtime)) { return; } } } } error_log($message, 3, $file); } /** * 清除文本部分字符 * * @param string $message */ public static function clear($message) { return str_replace(array( , , ) , , $message); } /** * sql语句字符清理 * * @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; } /** * 显示错误 * * @static * @access public * @param string $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 << $msg) { $k++; echo ''; echo '' . $k . ' '; echo '' . $msg['file'] . ' '; echo '' . $msg['line'] . ' '; echo '' . $msg['function'] . ' '; echo '
'; } } else { echo '' . $phpmsg . '
'; } echo '
'; } echo
效果图:php系统异常处理类程序