目錄
$title Error
首頁 php教程 php手册 PHP系统异常处理类程序

PHP系统异常处理类程序

May 25, 2016 pm 04:47 PM
catch explode fopen foreach substr

以前我们用过的异常处理函数都是单个的,下面我找到一个非常的不错的异常处理类系统,不但可以控制错误还能给出好的界面哦。

<?php
// 自定义异常函数
set_exception_handler(&#39;handle_exception&#39;);
// 自定义错误函数
set_error_handler(&#39;handle_error&#39;);
/**
 * 异常处理
 *
 * @param mixed $exception 异常对象
 * @author www.phprm.com
 */
function handle_exception($exception) {
    Error::exceptionError($exception);
}
/**
 * 错误处理
 *
 * @param string $errNo 错误代码
 * @param string $errStr 错误信息
 * @param string $errFile 出错文件
 * @param string $errLine 出错行
 * @author www.phprm.com
 */
function handle_error($errNo, $errStr, $errFile, $errLine) {
    if ($errNo) {
        Error::systemError($errStr, false, true, false);
    }
}
/**
 * 系统错误处理
 *
 * @author http://www.phprm.com
 */
class Error {
    public static function systemError($message, $show = true, $save = true, $halt = true) {
        list($showTrace, $logTrace) = self::debugBacktrace();
        if ($save) {
            $messageSave = &#39;<b>&#39; . $message . &#39;</b><br /><b>PHP:</b>&#39; . $logTrace;
            self::writeErrorLog($messageSave);
        }
        if ($show) {
            self::showError(&#39;system&#39;, "<li>$message</li>", $showTrace, 0);
        }
        if ($halt) {
            exit();
        } else {
            return $message;
        }
    }
    /**
     * 代码执行过程回溯信息
     *
     * @static
     * @access public
     */
    public static function debugBacktrace() {
        $skipFunc[] = &#39;Error->debugBacktrace&#39;;
        $show = $log = &#39;&#39;;
        $debugBacktrace = debug_backtrace();
        ksort($debugBacktrace);
        foreach ($debugBacktrace as $k => $error) {
            if (!isset($error[&#39;file&#39;])) {
                // 利用反射API来获取方法/函数所在的文件和行数
                try {
                    if (isset($error[&#39;class&#39;])) {
                        $reflection = new ReflectionMethod($error[&#39;class&#39;], $error[&#39;function&#39;]);
                    } else {
                        $reflection = new ReflectionFunction($error[&#39;function&#39;]);
                    }
                    $error[&#39;file&#39;] = $reflection->getFileName();
                    $error[&#39;line&#39;] = $reflection->getStartLine();
                }
                catch(Exception $e) {
                    continue;
                }
            }
            $file = str_replace(SITE_PATH, &#39;&#39;, $error[&#39;file&#39;]);
            $func = isset($error[&#39;class&#39;]) ? $error[&#39;class&#39;] : &#39;&#39;;
            $func.= isset($error[&#39;type&#39;]) ? $error[&#39;type&#39;] : &#39;&#39;;
            $func.= isset($error[&#39;function&#39;]) ? $error[&#39;function&#39;] : &#39;&#39;;
            if (in_array($func, $skipFunc)) {
                break;
            }
            $error[&#39;line&#39;] = sprintf(&#39;%04d&#39;, $error[&#39;line&#39;]);
            $show.= &#39;<li>[Line: &#39; . $error[&#39;line&#39;] . &#39;]&#39; . $file . &#39;(&#39; . $func . &#39;)</li>&#39;;
            $log.= !empty($log) ? &#39; -> &#39; : &#39;&#39;;
            $log.= $file . &#39;:&#39; . $error[&#39;line&#39;];
        }
        return array(
            $show,
            $log
        );
    }
    /**
     * 异常处理
     *
     * @static
     * @access public
     * @param mixed $exception
     */
    public static function exceptionError($exception) {
        if ($exception instanceof DbException) {
            $type = &#39;db&#39;;
        } else {
            $type = &#39;system&#39;;
        }
        if ($type == &#39;db&#39;) {
            $errorMsg = &#39;(&#39; . $exception->getCode() . &#39;) &#39;;
            $errorMsg.= self::sqlClear($exception->getMessage() , $exception->getDbConfig());
            if ($exception->getSql()) {
                $errorMsg.= &#39;<div class="sql">&#39;;
                $errorMsg.= self::sqlClear($exception->getSql() , $exception->getDbConfig());
                $errorMsg.= &#39;</div>&#39;;
            }
        } else {
            $errorMsg = $exception->getMessage();
        }
        $trace = $exception->getTrace();
        krsort($trace);
        $trace[] = array(
            &#39;file&#39; => $exception->getFile() ,
            &#39;line&#39; => $exception->getLine() ,
            &#39;function&#39; => &#39;break&#39;
        );
        $phpMsg = array();
        foreach ($trace as $error) {
            if (!empty($error[&#39;function&#39;])) {
                $fun = &#39;&#39;;
                if (!empty($error[&#39;class&#39;])) {
                    $fun.= $error[&#39;class&#39;] . $error[&#39;type&#39;];
                }
                $fun.= $error[&#39;function&#39;] . &#39;(&#39;;
                if (!empty($error[&#39;args&#39;])) {
                    $mark = &#39;&#39;;
                    foreach ($error[&#39;args&#39;] as $arg) {
                        $fun.= $mark;
                        if (is_array($arg)) {
                            $fun.= &#39;Array&#39;;
                        } elseif (is_bool($arg)) {
                            $fun.= $arg ? &#39;true&#39; : &#39;false&#39;;
                        } elseif (is_int($arg)) {
                            $fun.= (defined(&#39;SITE_DEBUG&#39;) && SITE_DEBUG) ? $arg : &#39;%d&#39;;
                        } elseif (is_float($arg)) {
                            $fun.= (defined(&#39;SITE_DEBUG&#39;) && SITE_DEBUG) ? $arg : &#39;%f&#39;;
                        } else {
                            $fun.= (defined(&#39;SITE_DEBUG&#39;) && SITE_DEBUG) ? &#39;&#39;&#39; . htmlspecialchars(substr(self::clear($arg), 0, 10)) . (strlen($arg) > 10 ? &#39; . . . &#39; : &#39;&#39;) . &#39;&#39;&#39; : &#39;%s&#39;;
                        }
                        $mark = &#39;, &#39;;
                    }
                }
                $fun.= &#39;)&#39;;
                $error[&#39;function&#39;] = $fun;
            }
            if (!isset($error[&#39;line&#39;])) {
                continue;
            }
            $phpMsg[] = array(
                &#39;file&#39; => str_replace(array(
                    SITE_PATH,
                    &#39;&#39;
                ) , array(
                    &#39;&#39;,
                    &#39;/&#39;
                ) , $error[&#39;file&#39;]) ,
                &#39;line&#39; => $error[&#39;line&#39;],
                &#39;function&#39; => $error[&#39;function&#39;]
            );
        }
        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 . &#39;/&#39; . date(&#39;Y.m.d&#39;) . &#39;_errorlog.php&#39;;
        $hash = md5($message);
        $userId = 0;
        $ip = get_client_ip();
        $user = &#39;<b>User:</b> userId=&#39; . intval($userId) . &#39;; IP=&#39; . $ip . &#39;; RIP:&#39; . $_SERVER[&#39;REMOTE_ADDR&#39;];
        $uri = &#39;Request: &#39; . htmlspecialchars(self::clear($_SERVER[&#39;REQUEST_URI&#39;]));
        $message = "<?php exit;?> {$time} $message $hash $user $uri ";
        // 判断该$message是否在时间间隔$maxtime内已记录过,有,则不用再记录了
        if (is_file($file)) {
            $fp = @fopen($file, &#39;rb&#39;);
            $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] != &#39;<?php exit;?>&#39;) {
                        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(&#39;SITE_DEBUG&#39;) && SITE_DEBUG)) {
            $message = str_replace($dbConfig[&#39;database&#39;], &#39;***&#39;, $message);
            //$message = str_replace($dbConfig[&#39;prefix&#39;], &#39;***&#39;, $message);
            $message = str_replace(C(&#39;DB_PREFIX&#39;) , &#39;***&#39;, $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 = &#39;&#39;) {
        global $_G;
        $errorMsg = str_replace(SITE_PATH, &#39;&#39;, $errorMsg);
        ob_end_clean();
        $host = $_SERVER[&#39;HTTP_HOST&#39;];
        $title = $type == &#39;db&#39; ? &#39;Database&#39; : &#39;System&#39;;
        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[&#39;config&#39;][&#39;output&#39;][&#39;charset&#39;]}" />
 <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 id="title-nbsp-Error">$title Error</h1>
<div class=&#39;info&#39;>$errorMsg</div>
EOT;
        if (!empty($phpMsg)) {
            echo &#39;<div class="info">&#39;;
            echo &#39;<p><strong>PHP Debug</strong></p>&#39;;
            echo &#39;<table cellpadding="5" cellspacing="1" width="100%" class="table"><tbody>&#39;;
            if (is_array($phpMsg)) {
                echo &#39;<tr class="bg2"><td>No.</td><td>File</td><td>Line</td><td>Code</td></tr>&#39;;
                foreach ($phpMsg as $k => $msg) {
                    $k++;
                    echo &#39;<tr class="bg1">&#39;;
                    echo &#39;<td>&#39; . $k . &#39;</td>&#39;;
                    echo &#39;<td>&#39; . $msg[&#39;file&#39;] . &#39;</td>&#39;;
                    echo &#39;<td>&#39; . $msg[&#39;line&#39;] . &#39;</td>&#39;;
                    echo &#39;<td>&#39; . $msg[&#39;function&#39;] . &#39;</td>&#39;;
                    echo &#39;</tr>&#39;;
                }
            } else {
                echo &#39;<tr><td><ul>&#39; . $phpMsg . &#39;</ul></td></tr>&#39;;
            }
            echo &#39;</tbody></table></div>&#39;;
        }
        echo <<<EOT
</div>
</body>
</html>
EOT;
        exit();
    }
}
/**
 * DB异常类
 *
 * @author www.phprm.com
 */
class DbException extends Exception {
    protected $sql;
    protected $dbConfig; // 当前数据库配置信息
    public function __construct($message, $code = 0, $sql = &#39;&#39;, $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系统异常处理类程序


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼? Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼? Apr 27, 2023 pm 03:40 PM

一、Iterator和foreach的區別多態差異(foreach底層就是Iterator)Iterator是一個介面類型,他不關心集合或數組的類型;for和foreach都需要先知道集合的類型,甚至是集合內元素的類型; 1.為啥說foreach底層就是Iterator寫的程式碼:反編譯程式碼:二、foreach與iterator時remove的差別先來看阿里java開發手冊但1的時候不會報錯,2的時候就會報錯(java. util.ConcurrentModificationException)首

php如何判斷foreach循環到第幾個 php如何判斷foreach循環到第幾個 Jul 10, 2023 pm 02:18 PM

php判斷foreach循環到第幾個的步驟:1、創建一個「$fruits」的數組;2、創建一個計數器變數「$counter」初始值為0;3、使用「foreach」循環遍歷數組,並在循環體中增加計數器變數的值,再輸出每個元素和它們的索引;4、在「foreach」循環體外輸出計數器變數的值,以確認循環到了第幾個元素。

如何解決PHP Warning: fopen(): SSL operation failed in file.php on line X 如何解決PHP Warning: fopen(): SSL operation failed in file.php on line X Aug 25, 2023 am 09:22 AM

如何解決PHPWarning:fopen():SSLoperationfailedinfile.phponlineX在PHP程式設計中,我們經常使用fopen函數來開啟檔案或URL,並進行相關操作。然而,在使用fopen函數時,有時候會遇到類似Warning:fopen():SSLoperationfailedinfile.p

如何解決PHP Warning: fopen(): failed to open stream: Permission denied 如何解決PHP Warning: fopen(): failed to open stream: Permission denied Aug 20, 2023 pm 01:45 PM

如何解決PHPWarning:fopen():failedtoopenstream:Permissiondenied在開發PHP程式的過程中,我們常常會遇到一些報錯訊息,例如PHPWarning:fopen():failedtoopenstream:Permissiondenied。這個錯誤通常是因為檔案或目錄權限不正

如何解決PHP Warning: fopen(): failed to open stream: No such file or directory 如何解決PHP Warning: fopen(): failed to open stream: No such file or directory Aug 19, 2023 am 10:44 AM

如何解決PHPWarning:fopen():failedtoopenstream:Nosuchfileordirectory在使用PHP開發過程中,我們常常會遇到一些檔案操作的問題,其中之一就是"PHPWarning:fopen():failedtoopenstream:Nosuchfileordirectory

PHP傳回一個鍵值翻轉後的陣列 PHP傳回一個鍵值翻轉後的陣列 Mar 21, 2024 pm 02:10 PM

這篇文章將為大家詳細講解有關PHP返回一個鍵值翻轉後的數組,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章後可以有所收穫。 PHP鍵值翻轉數組鍵值翻轉是一種對數組進行的操作,它將數組中的鍵和值進行交換,產生一個新的數組,其中原始鍵作為值,原始值作為鍵。實作方法在php中,可以透過以下方法對陣列進行鍵值翻轉:array_flip()函數:array_flip()函數專門用於鍵值翻轉操作。它接收一個數組作為參數,並傳回一個新的數組,其中鍵和值已交換。 $original_array=[

Matlab中fopen函數用法 Matlab中fopen函數用法 Nov 28, 2023 am 11:03 AM

在Matlab中,fopen函數用於開啟檔案並傳回檔案標識符,以便後續對檔案進行讀取或寫入操作。根據需要選擇適當的權限選項來開啟文件,並在操作完成後及時關閉文件。需要注意的是,打開文件後需要確保在不再需要文件時及時關閉文件,以釋放系統資源。另外,如果檔案開啟失敗或操作出錯,可以透過錯誤處理機制進行對應的處理。

PHP explode函數使用方法與報錯解決 PHP explode函數使用方法與報錯解決 Mar 10, 2024 am 09:18 AM

PHP中的explode函數是用來將字串分割成陣列的函數,它非常常用且靈活。在使用explode函數的過程中,常常會遇到一些報錯和問題,本文將介紹explode函數的基本用法並提供一些解決報錯的方法。一、explode函數基本用法在PHP中,explode函數的基本語法如下:explode(string$separator,string$stri

See all articles