香港高速VIP云机房火爆上线啦!无需备案,开通即用!配套《巅云自助建站系统3.0》将带给您飞一般的可视化拖拽建站体验,欢迎免费体验。

建站新闻

一个显示效果非常不错的PHP错误、异常处理类
一佰互联网站建设(www.yinxi.net) 发布时间:2019-04-29 09:01:55 浏览数: 8
0

一、效果图:


二、实现代码

复制代码 代码如下:<?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 = "<b>" . $message . "</b><br /><b>PHP:</b>" . $logTrace;
   self::writeErrorLog($messageSave);
  }

  if ($show) {
   self::showError("system", "<li>$message</li>", $showTrace, 0);
  }

  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 .= "<li>[Line: " . $error["line"] . "]" . $file . "(" . $func . ")</li>";
   $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 .= "<div class="sql">";
    $errorMsg .= self::sqlClear($exception->getSql(), $exception->getDbConfig());
    $errorMsg .= "</div>";
   }
  } 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 = "<b>User:</b> userId=" . intval($userId) . "; IP=" . $ip . "; RIP:" . $_SERVER["REMOTE_ADDR"];
  $uri = "Request: " . htmlspecialchars(self::clear($_SERVER["REQUEST_URI"]));
  $message = "<?php exit;?> {$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] != "<?php exit;?>") {
       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 <<<EOT
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
 <title>$host - $title Error</title>
 <meta http-equiv="Content-Type" content="text/html; charset={$_G["config"]["output"]["charset"]}" />
 <meta name="ROBOTS" content="NOINDEX,NOFOLLOW,NOARCHIVE" />
 <style type="text/css">
 <!--
 body { background-color: white; color: black; font: 9pt/11pt verdana, arial, sans-serif;}
 #container {margin: 10px;}
 #message {width: 1024px; color: black;}
 .red {color: red;}
 a:link {font: 9pt/11pt verdana, arial, sans-serif; color: red;}
 a:visited {font: 9pt/11pt verdana, arial, sans-serif; color: #4e4e4e;}
 h1 {color: #FF0000; font: 18pt "Verdana"; margin-bottom: 0.5em;}
 .bg1 {background-color: #FFFFCC;}
 .bg2 {background-color: #EEEEEE;}
 .table {background: #AAAAAA; font: 11pt Menlo,Consolas,"Lucida Console"}
 .info {
  background: none repeat scroll 0 0 #F3F3F3;
  border: 0px solid #aaaaaa;
  border-radius: 10px 10px 10px 10px;
  color: #000000;
  font-size: 11pt;
  line-height: 160%;
  margin-bottom: 1em;
  padding: 1em;
 }

 .help {
  background: #F3F3F3;
  border-radius: 10px 10px 10px 10px;
  font: 12px verdana, arial, sans-serif;
  text-align: center;
  line-height: 160%;
  padding: 1em;
 }

 .sql {
  background: none repeat scroll 0 0 #FFFFCC;
  border: 1px solid #aaaaaa;
  color: #000000;
  font: arial, sans-serif;
  font-size: 9pt;
  line-height: 160%;
  margin-top: 1em;
  padding: 4px;
 }
 -->
 </style>
</head>
<body>
<div id="container">
<h1>$title Error</h1>
<div class="info">$errorMsg</div>
EOT;
  if (!empty($phpMsg)) {
   echo "<div class="info">";
   echo "<p><strong>PHP Debug</strong></p>";
   echo "<table cellpadding="5" cellspacing="1" width="100%" class="table"><tbody>";
   if (is_array($phpMsg)) {
    echo "<tr class="bg2"><td>No.</td><td>File</td><td>Line</td><td>Code</td></tr>";
    foreach ($phpMsg as $k => $msg) {
     $k++;
     echo "<tr class="bg1">";
     echo "<td>" . $k . "</td>";
     echo "<td>" . $msg["file"] . "</td>";
     echo "<td>" . $msg["line"] . "</td>";
     echo "<td>" . $msg["function"] . "</td>";
     echo "</tr>";
    }
   } else {
    echo "<tr><td><ul>" . $phpMsg . "</ul></td></tr>";
   }
   echo "</tbody></table></div>";
  }
  echo <<<EOT
</div>
</body>
</html>
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;
 }
}

一佰互联是全国知名建站品牌服务商,我们有九年网站建设、网站制作、网页设计、php开发和域名注册及虚拟主机服务经验,提供的自助建站服务更是全国有名。近年来还整合团队优势自主开发了可视化多用户”巅云建站系统“3.0平台版,拖拽排版网站制作设计,轻松实现pc站、手机微网站、小程序、APP一体化全网营销网站建设 ,已成功的为全国上百家网络公司提供自助建站平台搭建服务。

上一篇:php设置session值和cookies的学习示例
下一篇: 一漂亮的PHP图片验证码实例
[返回新闻列表]

相关新闻more

20
05月
【保定网站优化】常见的网站内部优化方式_巅云

【】常见的 网站链接的优化涉及很多方面。第一应该有一个百度推荐的网站结构一一扁平的树形网状结构;其次,要对导航页面进行规划,要充分考虑到... >>详情

18
05月
网站优化:避免网站流量大损失的SEO策略_巅

关于受到非法链接指向而被惩罚的案例很多,不久前moz就有一个客户受到了这种的情况。受到非法链接指向被降权,有时候幸运的话,在几个月后就可以恢... >>详情

22
04月
css如何实现数字分页效果代码及步骤

相当数量的网站都使用数字分页效果,例如本站的分页也是采用此方式,还算是比较美观使用吧。 代码实例如下 复制代码代码如下: <!DOCT... >>详情

27
03月
2018小程序关键词-微信独大、大厂涌入

简介:截至2018年11月,微信小程序总量超过120万,与Q2阶段的100万相比较,增长了20%,小程序市场规模仍然保持快速增长的趋势。小程... >>详情

营业执照. cdn加速服务 备案系统认证 网络安全协会 我们的支付方式AAA认证
上海 北京 深圳 广州 天津 杭州 南京 武汉 成都 沈阳 大连 长沙 济南 青岛 苏州 福州 无锡 哈尔滨 宁波 重庆 大庆 厦门 西安 长春 珠海 郑州 海口 昆明 太原 石家庄 温州 合肥 乌鲁木齐 南宁 南通 合肥 兰州 呼和浩特 贵阳 烟台 秦皇岛 包头 唐山 银川 汕头 连云港 威海 西宁 湛江 北海 万州 涪陵 长寿 黔江 永川 丰都 忠县 江津 南川 开县 云阳 万盛 梁平 垫江 巫山 城口 建站宝盒 免费建站 门户网站建设 微信网站 手机网站 门户网站制作

7x24小时服务电话:18581389571 传真:023-85725751 免费建站交流群:236412099 139947842(自助建站交流) E-Mail:post@yinxi.net 网站投诉:
重庆楚捷科技有限公司 一佰互联©版权所有 自助建站(www.yinxi.net,Inc.) 2001-2020 All Rights Reserved 本站程序受法律保护,网站法律顾问:ITLAW-庄毅雄律师
中华人民共和国信息产业部网站备案号:渝ICP备12000592号