目次
$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 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Java ArrayList を走査するときに要素を削除するために foreach と iterator を使用することの違いは何ですか? Java ArrayList を走査するときに要素を削除するために foreach と iterator を使用することの違いは何ですか? Apr 27, 2023 pm 03:40 PM

1. Iterator と foreach の違いはポリモーフィックな違いです (foreach の最下層は Iterator です) Iterator はインターフェイス型であり、コレクションや配列の型を気にしません; for と foreach の両方がコレクションの型を知る必要がありますまず、コレクション内の要素の種類についても; 1. foreach の最下層はイテレータによって記述されたコードであると言われる理由: 逆コンパイルされたコード: 2. foreach の削除とイテレータの違い まず、Alibaba を見てください。 Java 開発マニュアル。ただし、ケース 1 ではエラーは報告されず、ケース 2 (java.util.ConcurrentModificationException) では最初にエラーが報告されます。

PHPでforeachループの数を確認する方法 PHPでforeachループの数を確認する方法 Jul 10, 2023 pm 02:18 PM

PHP が foreach ループの数を決定する手順: 1. "$fruits" の配列を作成します; 2. 初期値 0 でカウンタ変数 "$counter" を作成します; 3. "foreach" を使用してループします配列を介してループ本体内のカウンタ変数の値を増加させ、各要素とそのインデックスを出力します; 4. foreach ループの外側にカウンタ変数の値を出力し、ループがどの要素に到達したかを確認します。

PHP 警告: fopen(): SSL 操作が file.php の X 行目で失敗した場合の解決方法 PHP 警告: fopen(): SSL 操作が file.php の X 行目で失敗した場合の解決方法 Aug 25, 2023 am 09:22 AM

PHPWarning:fopen():SSLoperationfailedinfile.phponlineX を解決する方法 PHP プログラミングでは、fopen 関数を使用してファイルまたは URL を開いて関連する操作を実行することがよくあります。ただし、fopen 関数を使用すると、Warning:fopen():SSLoperationfailedinfile.p のようなエラーが発生することがあります。

PHP 警告の解決方法: fopen(): ストリームを開けませんでした: 許可が拒否されました PHP 警告の解決方法: fopen(): ストリームを開けませんでした: 許可が拒否されました Aug 20, 2023 pm 01:45 PM

PHPWarning:fopen():failedtoopenstream:Permissiondenied を解決する方法 PHP プログラムの開発プロセスでは、PHPWarning:fopen():failedtoopenstream:Permissiondenied などのエラー メッセージに遭遇することがよくあります。このエラーは通常、ファイルまたはディレクトリのアクセス許可が正しくないことが原因で発生します。

PHP 警告の解決方法: fopen(): ストリームを開けませんでした: そのようなファイルまたはディレクトリはありません PHP 警告の解決方法: fopen(): ストリームを開けませんでした: そのようなファイルまたはディレクトリはありません Aug 19, 2023 am 10:44 AM

PHPWarning:fopen():failedtoopenstream:No suchfileordirectory PHP 開発を使用する過程で、ファイル操作の問題がよく発生します。その 1 つが「PHPWarning:fopen():failedtoopenstream:No suchfileordirectory」です。

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関数は、文字列を配列に分割するために使用される関数で、非常に一般的で柔軟性があります。分解関数を使用する過程で、エラーや問題が発生することがよくありますが、この記事では、分解関数の基本的な使用方法を紹介し、エラー報告を解決するいくつかの方法を紹介します。 1.explode関数の基本的な使い方 PHPでは、explode関数の基本的な構文は次のとおりです。explode(string$separator,string$stri

See all articles