Jadual Kandungan
$title Error
Rumah pembangunan bahagian belakang tutorial php 一个显示效果非常不错的PHP错误、异常处理类_php实例

一个显示效果非常不错的PHP错误、异常处理类_php实例

Jun 07, 2016 pm 05:21 PM
php

一、效果图:

一个显示效果非常不错的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', "

  • $message
  • ", $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 .= '

  • [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; // 暂时不写入

      $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


     $host - $title Error
     
     
     



    $title Error


    $errorMsg

    EOT;
      if (!empty($phpMsg)) {
       echo '
    ';
       echo '

    PHP Debug

    ';
       echo '';
       if (is_array($phpMsg)) {
        echo '';
        foreach ($phpMsg as $k => $msg) {
         $k++;
         echo '';
         echo '';
         echo '';
         echo '';
         echo '';
         echo '';
        }
       } else {
        echo '';
       }
       echo '
    No. File Line Code
    ' . $k . '' . $msg['file'] . '' . $msg['line'] . '' . $msg['function'] . '
      ' . $phpMsg . '
    ';
      }
      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;
     }
    }

    Kenyataan Laman Web ini
    Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

    Tag artikel panas

    Notepad++7.3.1

    Notepad++7.3.1

    Editor kod yang mudah digunakan dan percuma

    SublimeText3 versi Cina

    SublimeText3 versi Cina

    Versi Cina, sangat mudah digunakan

    Hantar Studio 13.0.1

    Hantar Studio 13.0.1

    Persekitaran pembangunan bersepadu PHP yang berkuasa

    Dreamweaver CS6

    Dreamweaver CS6

    Alat pembangunan web visual

    SublimeText3 versi Mac

    SublimeText3 versi Mac

    Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

    Panduan Pemasangan dan Naik Taraf PHP 8.4 untuk Ubuntu dan Debian Panduan Pemasangan dan Naik Taraf PHP 8.4 untuk Ubuntu dan Debian Dec 24, 2024 pm 04:42 PM

    Panduan Pemasangan dan Naik Taraf PHP 8.4 untuk Ubuntu dan Debian

    Tarikh dan Masa CakePHP Tarikh dan Masa CakePHP Sep 10, 2024 pm 05:27 PM

    Tarikh dan Masa CakePHP

    Konfigurasi Projek CakePHP Konfigurasi Projek CakePHP Sep 10, 2024 pm 05:25 PM

    Konfigurasi Projek CakePHP

    Muat naik Fail CakePHP Muat naik Fail CakePHP Sep 10, 2024 pm 05:27 PM

    Muat naik Fail CakePHP

    Penghalaan CakePHP Penghalaan CakePHP Sep 10, 2024 pm 05:25 PM

    Penghalaan CakePHP

    Bincangkan CakePHP Bincangkan CakePHP Sep 10, 2024 pm 05:28 PM

    Bincangkan CakePHP

    Panduan Ringkas CakePHP Panduan Ringkas CakePHP Sep 10, 2024 pm 05:27 PM

    Panduan Ringkas CakePHP

    Cara Menyediakan Kod Visual Studio (Kod VS) untuk Pembangunan PHP Cara Menyediakan Kod Visual Studio (Kod VS) untuk Pembangunan PHP Dec 20, 2024 am 11:31 AM

    Cara Menyediakan Kod Visual Studio (Kod VS) untuk Pembangunan PHP

    See all articles