@H_502_0@
<TABLE border=0 cellSpacing=3 cellPadding=0 width="100%">
403/2014321101634983.png?2014221101651">
二、实现代码 @H_502_0@
代码如下:
PHP
@H_502_0@// 自定义异常函数
set_exception_handler('handle_exception'); @H_502_0@// 自定义错误函数
set_error_handler('handle_error'); @H_502_0@/**
* 异常处理
*
* @param mixed $exception 异常对象
* @author blog.snsgou.com
*/
function handle_exception($exception) {
Error::exceptionError($exception);
} @H_502_0@/**
* 错误处理
*
* @param string $errNo 错误代码
* @param string $errStr 错误信息
* @param string $errFile 出错文件
* @param string $errLine 出错行
* @author blog.snsgou.com
*/
function handle_error($errNo,$errStr,$errFile,$errLine) {
if ($errNo) {
Error::systemError($errStr,false,true,false);
}
} @H_502_0@/**
* 系统错误处理
*
* @author blog.snsgou.com
*/
class Error { @H_502_0@public static function systemError($message,$show = true,$save = true,$halt = true) { @H_502_0@list($showTrace,$logTrace) = self::debugBacktrace(); @H_502_0@if ($save) {
$messageSave = '' . $message . '
PHP:' . $logTrace;
self::writeErrorLog($messageSave);
} @H_502_0@if ($show) {
self::showError('system',"$message ",$showTrace,0);
} @H_502_0@if ($halt) {
exit();
} else {
return $message;
}
} @H_502_0@/**
* 代码执行过程回溯信息
*
* @static
* @access public
*/
public static function debugBacktrace() {
$skipFunc[] = 'Error->debugBacktrace'; @H_502_0@$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;
}
} @H_502_0@$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']); @H_502_0@$show .= '[Line: ' . $error['line'] . ']' . $file . '(' . $func . ') ';
$log .= !empty($log) ? ' -> ' : '';
$log .= $file . ':' . $error['line'];
}
return array($show,$log);
} @H_502_0@/**
* 异常处理
*
* @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 .= '';
}
} 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),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();
} @H_502_0@/**
* 记录错误日志
*
* @static
* @access public
* @param string $message
*/
public static function writeErrorLog($message) { @H_502_0@return false; // 暂时不写入 @H_502_0@$message = self::clear($message);
$time = time();
$file = LOG_PATH . '/' . date('Y.m.d') . '_errorlog.PHP';
$hash = md5($message); @H_502_0@$userId = 0;
$ip = get_client_ip(); @H_502_0@$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"; @H_502_0@// 判断该$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("\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;
}
}
}
} @H_502_0@error_log($message,3,$file);
} @H_502_0@/**
* 清除文本部分字符
*
* @param string $message
*/
public static function clear($message) {
return str_replace(array("\t","\r","\n")," ",$message);
} @H_502_0@/**
* 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;
} @H_502_0@/**
* 显示错误
*
* @static
* @access public
* @param string $type 错误类型 db,system
* @param string $errorMsg
* @param string $PHPMsg
*/
public static function showError($type,$PHPMsg = '') {
global $_G; @H_502_0@$errorMsg = str_replace(SITE_PATH,$errorMsg);
ob_end_clean();
$host = $_SERVER['HTTP_HOST'];
$title = $type == 'db' ? 'Database' : 'System';
echo <<
$host - $title Error
EOT;
if (!empty($PHPMsg)) {
echo '
EOT;
exit();
}
} @H_502_0@/**
* DB异常类
*
* @author blog.snsgou.com
*/
class DbException extends Exception { @H_502_0@protected $sql;
protected $dbConfig;// 当前数据库配置信息 @H_502_0@public function __construct($message,$code = 0,$sql = '',$dbConfig = array()) {
$this->sql = $sql;
$this->dbConfig = $dbConfig;
parent::__construct($message,$code);
} @H_502_0@public function getsql() {
return $this->sql;
} @H_502_0@public function getDbConfig() {
return $this->dbConfig;
}
}
set_exception_handler('handle_exception'); @H_502_0@// 自定义错误函数
set_error_handler('handle_error'); @H_502_0@/**
* 异常处理
*
* @param mixed $exception 异常对象
* @author blog.snsgou.com
*/
function handle_exception($exception) {
Error::exceptionError($exception);
} @H_502_0@/**
* 错误处理
*
* @param string $errNo 错误代码
* @param string $errStr 错误信息
* @param string $errFile 出错文件
* @param string $errLine 出错行
* @author blog.snsgou.com
*/
function handle_error($errNo,$errStr,$errFile,$errLine) {
if ($errNo) {
Error::systemError($errStr,false,true,false);
}
} @H_502_0@/**
* 系统错误处理
*
* @author blog.snsgou.com
*/
class Error { @H_502_0@public static function systemError($message,$show = true,$save = true,$halt = true) { @H_502_0@list($showTrace,$logTrace) = self::debugBacktrace(); @H_502_0@if ($save) {
$messageSave = '' . $message . '
PHP:' . $logTrace;
self::writeErrorLog($messageSave);
} @H_502_0@if ($show) {
self::showError('system',"
} @H_502_0@if ($halt) {
exit();
} else {
return $message;
}
} @H_502_0@/**
* 代码执行过程回溯信息
*
* @static
* @access public
*/
public static function debugBacktrace() {
$skipFunc[] = 'Error->debugBacktrace'; @H_502_0@$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;
}
} @H_502_0@$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']); @H_502_0@$show .= '
$log .= !empty($log) ? ' -> ' : '';
$log .= $file . ':' . $error['line'];
}
return array($show,$log);
} @H_502_0@/**
* 异常处理
*
* @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 .= '';
}
} 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),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();
} @H_502_0@/**
* 记录错误日志
*
* @static
* @access public
* @param string $message
*/
public static function writeErrorLog($message) { @H_502_0@return false; // 暂时不写入 @H_502_0@$message = self::clear($message);
$time = time();
$file = LOG_PATH . '/' . date('Y.m.d') . '_errorlog.PHP';
$hash = md5($message); @H_502_0@$userId = 0;
$ip = get_client_ip(); @H_502_0@$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"; @H_502_0@// 判断该$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("\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;
}
}
}
} @H_502_0@error_log($message,3,$file);
} @H_502_0@/**
* 清除文本部分字符
*
* @param string $message
*/
public static function clear($message) {
return str_replace(array("\t","\r","\n")," ",$message);
} @H_502_0@/**
* 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;
} @H_502_0@/**
* 显示错误
*
* @static
* @access public
* @param string $type 错误类型 db,system
* @param string $errorMsg
* @param string $PHPMsg
*/
public static function showError($type,$PHPMsg = '') {
global $_G; @H_502_0@$errorMsg = str_replace(SITE_PATH,$errorMsg);
ob_end_clean();
$host = $_SERVER['HTTP_HOST'];
$title = $type == 'db' ? 'Database' : 'System';
echo <<
$title Error
$errorMsg
EOT;
if (!empty($PHPMsg)) {
echo '
echo '
echo '';
';
}
echo <<
PHP Debug
';echo '
echo ' | echo ' | echo ' | echo ' |
}
echo <<
EOT;
exit();
}
} @H_502_0@/**
* DB异常类
*
* @author blog.snsgou.com
*/
class DbException extends Exception { @H_502_0@protected $sql;
protected $dbConfig;// 当前数据库配置信息 @H_502_0@public function __construct($message,$code = 0,$sql = '',$dbConfig = array()) {
$this->sql = $sql;
$this->dbConfig = $dbConfig;
parent::__construct($message,$code);
} @H_502_0@public function getsql() {
return $this->sql;
} @H_502_0@public function getDbConfig() {
return $this->dbConfig;
}
}