ä¸ä¸ªæ¾ç¤ºææé常ä¸éçPHPé误ãå¼å¸¸å¤çç±»
è¿ç¯æç« ä¸»è¦ä»ç»äºä¸ä¸ªæ¾ç¤ºææé常ä¸éçPHPé误ãå¼å¸¸å¤çç±»,代ç æè·¯æ¸ æ°,åè½å¼ºå¤§,éè¦çæåå¯ä»¥åèä¸
ä¸ãææå¾ï¼
äºãå®ç°ä»£ç
å¤å¶ä»£ç 代ç å¦ä¸:
// èªå®ä¹å¼å¸¸å½æ°
set_exception_handler('handle_exception');
// èªå®ä¹é误å½æ°
set_error_handler('handle_error');
/**
* å¼å¸¸å¤ç
*
* @param mixed $exception å¼å¸¸å¯¹è±¡
* @author blog.snsgou.com
*/
function handle_exception($exception) {
Error::exceptionError($exception);
}
/**
* é误å¤ç
*
* @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);
}
}
/**
* ç³»ç»é误å¤ç
*
* @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', "
}
if ($halt) {
exit();
} else {
return $message;
}
}
/**
* 代ç æ§è¡è¿ç¨å溯信æ¯
*
* @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'])) {
// å©ç¨åå°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 .= '
$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; // ææ¶ä¸åå ¥
$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";
// å¤æ该$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;
}
}
}
}
error_log($message, 3, $file);
}
/**
* æ¸
é¤ææ¬é¨åå符
*
* @param string $message
*/
public static function clear($message) {
return str_replace(array("\t", "\r", "\n"), " ", $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
$title Error
EOT;
if (!empty($phpMsg)) {
echo '
echo '
PHP Debug
';echo '
No. | File | Line | Code |
' . $k . ' | ';' . $msg['file'] . ' | ';' . $msg['line'] . ' | ';' . $msg['function'] . ' | ';
|
}
echo
EOT;
exit();
}
}
/**
* DBå¼å¸¸ç±»
*
* @author blog.snsgou.com
*/
class DbException extends Exception {
protected $sql;
protected $dbConfig; // å½åæ°æ®åºé
置信æ¯
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;
}
}