253 lines
7.0 KiB
PHP
253 lines
7.0 KiB
PHP
<?php
|
|
|
|
namespace top\library\exception;
|
|
|
|
use Throwable;
|
|
|
|
class BaseException extends \Exception {
|
|
|
|
public function __construct($message = "", $code = 0, Throwable $previous = null, $file = '', $line = '') {
|
|
if ($file)
|
|
$this->file = $file;
|
|
if ($line) {
|
|
$this->line = $line;
|
|
}
|
|
parent::__construct($message, $code, $previous);
|
|
}
|
|
|
|
public function syntaxHighlight($code) {
|
|
$code = preg_replace('/"(.*?)"/U', '"<span style="color: #007F00">$1</span>"', $code);
|
|
$code = preg_replace('/(\s)\b(.*?)((\b|\s)\()/U', '$1<span style="color: #aa0">$2</span>$3', $code);
|
|
$code = preg_replace('/(class)(.+)\s/', '<span style="color: #aa0;">$0</span>', $code);
|
|
$code = preg_replace('/(\/\/)(.+)\s/', '<span style="color: #ccc;">$0</span>', $code);
|
|
$code = preg_replace('/(\/\*.*?\*\/)/s', '<span style="color: #ccc;">$0</span>', $code);
|
|
$code = preg_replace('/(\[|\{|\}|\])/', '<strong>$1</strong>', $code);
|
|
$code = preg_replace('/(\(|\)|\->|\=>)/', '<span style="color: #9c9c9c;">$1</span>', $code);
|
|
$code = preg_replace('/(\$[a-zA-Z0-9_]+)/', '<span style="color: #ff5500">$1</span>', $code);
|
|
$code = preg_replace('/\b(print|echo|new|function|return|true|false|namespace|use|class|extends|implements)\b/', '<span style="color: #86bbf1">$1</span>', $code);
|
|
return $code;
|
|
}
|
|
|
|
/**
|
|
* @param $filename
|
|
* @param $line
|
|
* @return string
|
|
*/
|
|
private function readErrorFile($filename, $line) {
|
|
$file = file($filename);
|
|
$totalLine = count($file);
|
|
$offset = 10;
|
|
$offsetStart = $line - $offset;
|
|
$offsetEnd = $line + $offset;
|
|
$start = ($offsetStart <= 0) ? 2 : $offsetStart;
|
|
$end = ($offsetEnd > $totalLine) ? $totalLine : $offsetEnd;
|
|
$content = '';
|
|
for ($i = $start; $i <= $end; $i++) {
|
|
$content .= '<a ' . ($i == $line ? 'class="errLine"' : '') . '><span class="lineDetail"><b>' . $i . '</b>';
|
|
$content .= $this->syntaxHighlight(htmlspecialchars($file[$i - 1])) . '</span></a>';
|
|
}
|
|
return '<pre>' . $content . '</pre>';
|
|
}
|
|
|
|
/**
|
|
* @param \Exception|null $exception
|
|
*/
|
|
public function handler($exception = null) {
|
|
if (DEBUG) {
|
|
$message = htmlspecialchars($exception->getMessage());
|
|
$file = $exception->getFile();
|
|
$line = $exception->getLine();
|
|
$trace = $exception->getTraceAsString();
|
|
$content = '<div class="codeblock">' . $this->readErrorFile($file, $line) . '</div>';
|
|
$detail = '<div class="errorFileInfo word_wrap">位于 ' . $file . ' 第 ' . $line . ' 行</div>';
|
|
$detail .= $content . '<div class="traceblock"><a id="showTrace" href="javascript:;">查看Trace信息</a>';
|
|
$detail .= '<div id="traceDetail" style="display: none;"><pre class="word_wrap">' . $trace . '</pre></div></div>';
|
|
} else {
|
|
$message = '系统错误,请稍后重试。';
|
|
$detail = '<span>请打开调试模式以查看详细信息。</span>';
|
|
}
|
|
$message = $this->translateMessage($message);
|
|
$content = <<<EOF
|
|
<!DOCTYPE html>
|
|
<html lang="zh">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
|
|
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
|
<title>系统错误</title>
|
|
<script src="/resource/jquery.min.js"></script>
|
|
</head>
|
|
<body>
|
|
<style>
|
|
body,
|
|
h1,
|
|
h2,
|
|
h3,
|
|
h4,
|
|
h5,
|
|
h6,
|
|
hr,
|
|
p,
|
|
blockquote,
|
|
dl,
|
|
dt,
|
|
dd,
|
|
ul,
|
|
ol,
|
|
li,
|
|
pre,
|
|
form,
|
|
fieldset,
|
|
legend,
|
|
button,
|
|
input,
|
|
select,
|
|
textarea,
|
|
th,
|
|
td {
|
|
margin: 0;
|
|
padding: 0
|
|
}
|
|
* {
|
|
font-family: "Courier New";
|
|
font-weight: bold;
|
|
/*font-family: "Droid Sans Mono";*/
|
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
}
|
|
a {
|
|
text-decoration: none;
|
|
}
|
|
ul {
|
|
list-style: none;
|
|
}
|
|
body {
|
|
background: #eeeeee;
|
|
}
|
|
#showTrace {
|
|
color: #9c9c9c;
|
|
line-height: 25px;
|
|
}
|
|
.word_wrap {
|
|
white-space: pre-wrap!important;
|
|
word-wrap: break-word!important;
|
|
*white-space:normal!important;
|
|
}
|
|
.msg_box {
|
|
width: 82%;
|
|
height: auto;
|
|
margin: 20px auto;
|
|
background: #ffffff;
|
|
padding: 15px;
|
|
color: #9c9c9c;
|
|
font-size: 12px;
|
|
}
|
|
.msg_box .mainMessage {
|
|
color: #666666;
|
|
font-size: 14px;
|
|
}
|
|
.msg_box .detail {
|
|
margin-top: 10px;
|
|
}
|
|
.detail .codeblock {
|
|
width: 100%;
|
|
height: auto;
|
|
font-size: 12px;
|
|
margin: 10px auto;
|
|
border-radius: 5px;
|
|
border: 1px solid #EEEEEE;
|
|
overflow-x: scroll;
|
|
}
|
|
.detail .codeblock .errLine {
|
|
background: #f7e6e6 !important;
|
|
}
|
|
.detail .codeblock a {
|
|
display: block;
|
|
width: 100%;
|
|
height: 22px;
|
|
color: #9c9c9c;
|
|
line-height: 22px;
|
|
}
|
|
.detail .codeblock a:hover{
|
|
background: #fbfbfb;
|
|
}
|
|
.detail .codeblock b {
|
|
display: inline-block;
|
|
width: 45px;
|
|
height: auto;
|
|
text-align: center;
|
|
margin-right: 5px;
|
|
border-right: 1px solid #EEEEEE;
|
|
}
|
|
.detail .errorFileInfo {
|
|
width: 100%;
|
|
line-height: 20px;
|
|
}
|
|
.detail .traceblock {
|
|
width: 100%;
|
|
height: auto;
|
|
line-height: 16px;
|
|
}
|
|
.detail .traceblock pre {
|
|
margin-top: 5px;
|
|
}
|
|
.version {
|
|
width: 100%;
|
|
height: 22px;
|
|
color: #b9b9b9;
|
|
font-size: 12px;
|
|
text-align: center;
|
|
line-height: 22px;
|
|
margin: 0 auto;
|
|
padding-bottom: 20px;
|
|
}
|
|
</style>
|
|
<div class="msg_box">
|
|
<p class="mainMessage">{$message}</p>
|
|
<div class="detail">
|
|
{$detail}
|
|
</div>
|
|
</div>
|
|
<div class="version">TOP-framework</div>
|
|
<script>
|
|
$(function() {
|
|
var cb = $('.codeblock').width();
|
|
var d = $('.lineDetail');
|
|
var v = 0;
|
|
for(var i = 0; i < d.length; i++) {
|
|
if ($(d[i]).width() > v) {
|
|
v = $(d[i]).width();
|
|
}
|
|
}
|
|
if (v < cb) {
|
|
$('.codeblock').css({
|
|
'overflow-x': 'auto'
|
|
});
|
|
} else {
|
|
$('.codeblock').find('a').css({
|
|
'width': v + 'px'
|
|
});
|
|
}
|
|
});
|
|
$('#showTrace').click(function() {
|
|
$('#traceDetail').toggle();
|
|
var s = (($('#traceDetail').css('display') == 'block') ? '隐藏' : '查看') + 'Trace信息';
|
|
$(this).html(s);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|
|
EOF;
|
|
header("HTTP/1.1 404 Not Found");
|
|
echo $content;
|
|
exit;
|
|
}
|
|
|
|
public function translateMessage($message) {
|
|
$message = str_ireplace(
|
|
['Undefined variable', 'Undefined offset', 'Undefined index', 'syntax error,', 'Use of undefined constant'],
|
|
['未定义变量', '未定义数组下标', '未定义数组索引', '语法错误:', '使用未定义常量:'],
|
|
$message
|
|
);
|
|
return $message;
|
|
}
|
|
} |