';
139 | echo '
[' . $errType . ']
';
140 | echo '
';
141 | echo $errMsg;
142 | echo '
time: ' . date('Y-m-d H:i:s');
143 | echo '
';
144 |
145 | echo '
[PHP Debug]
';
146 | echo '
';
147 | echo $e->getTraceAsString();
148 | echo '
';
149 | echo '
';
150 | }
151 | }
152 |
153 | /**
154 | * 输出HTTP异常信息
155 | *
156 | * @param HttpException $e
157 | */
158 | protected function renderHttpException(HttpException $e)
159 | {
160 | App::respond(new Response($e->getCode(), $e->getMessage()));
161 | }
162 |
163 | /**
164 | * 是否http异常
165 | *
166 | * @param Exception|\ErrorException $e
167 | * @return bool
168 | */
169 | protected function isHttpException($e)
170 | {
171 | return ($e instanceof HttpException);
172 | }
173 |
174 | /**
175 | * 处理异常
176 | *
177 | * @param Exception|\ErrorException $e
178 | */
179 | public function handle($e)
180 | {
181 | $this->report($e);
182 | $this->render($e);
183 | exit;
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/src/Core/Http/Stream.php:
--------------------------------------------------------------------------------
1 |
10 | * @package Core\Http
11 | */
12 | class Stream implements StreamInterface
13 | {
14 | private $stream;
15 | private $readable;
16 | private $writable;
17 | private $seekable;
18 | private $size;
19 | private $uri;
20 |
21 | private static $readWriteMode = [
22 | 'read' => [
23 | 'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
24 | 'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
25 | 'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
26 | 'x+t' => true, 'c+t' => true, 'a+' => true
27 | ],
28 | 'write' => [
29 | 'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
30 | 'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
31 | 'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
32 | 'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true
33 | ]
34 | ];
35 |
36 | public function __construct($stream)
37 | {
38 | if (!is_resource($stream)) {
39 | throw new \InvalidArgumentException('stream must be a resource');
40 | }
41 | $this->stream = $stream;
42 | $meta = stream_get_meta_data($stream);
43 | $this->seekable = (bool)$meta['seekable'];
44 | $this->readable = isset(self::$readWriteMode['read'][$meta['mode']]);
45 | $this->writable = isset(self::$readWriteMode['write'][$meta['mode']]);
46 | $this->uri = isset($meta['uri']) ? $meta['uri'] : null;
47 | }
48 |
49 | public function __toString()
50 | {
51 | try {
52 | $this->seek(0);
53 | $contents = (string)stream_get_contents($this->stream);
54 | return $contents;
55 | } catch (\Exception $e) {
56 | }
57 | return '';
58 | }
59 |
60 | public function close()
61 | {
62 | if (isset($this->stream)) {
63 | if (is_resource($this->stream)) {
64 | fclose($this->stream);
65 | }
66 | $this->detach();
67 | }
68 | }
69 |
70 | public function detach()
71 | {
72 | if (!$this->stream) {
73 | return null;
74 | }
75 | $result = $this->stream;
76 | unset($this->stream);
77 | $this->size = $this->uri = null;
78 | $this->readable = $this->writable = $this->seekable = null;
79 | return $result;
80 | }
81 |
82 | public function getSize()
83 | {
84 | if ($this->size !== null) {
85 | return $this->size;
86 | }
87 | if (!$this->stream) {
88 | return null;
89 | }
90 | if ($this->uri) {
91 | clearstatcache(true, $this->uri);
92 | }
93 | $stats = fstat($this->stream);
94 | if (isset($stats['size'])) {
95 | $this->size = $stats['size'];
96 | return $this->size;
97 | }
98 | return null;
99 | }
100 |
101 | public function tell()
102 | {
103 | $result = ftell($this->stream);
104 | if ($result === false) {
105 | throw new \RuntimeException('Unable to determine stream position');
106 | }
107 | return $result;
108 | }
109 |
110 | public function eof()
111 | {
112 | return !$this->stream || feof($this->stream);
113 | }
114 |
115 | public function isSeekable()
116 | {
117 | return $this->seekable;
118 | }
119 |
120 | public function seek($offset, $whence = SEEK_SET)
121 | {
122 | if (!$this->seekable) {
123 | throw new \RuntimeException('Stream is not seekable');
124 | } elseif (fseek($this->stream, $offset, $whence) === -1) {
125 | throw new \RuntimeException('Unable to seek to stream position '
126 | . $offset . ' with whence ' . var_export($whence, true));
127 | }
128 | }
129 |
130 | public function rewind()
131 | {
132 | $this->seek(0);
133 | }
134 |
135 | public function isWritable()
136 | {
137 | return $this->writable;
138 | }
139 |
140 | public function write($string)
141 | {
142 | if (!$this->writable) {
143 | throw new \RuntimeException('Cannot write to a non-writable stream');
144 | }
145 | $this->size = null;
146 | $result = fwrite($this->stream, $string);
147 | if ($result === false) {
148 | throw new \RuntimeException('Unable to write to stream');
149 | }
150 | return $result;
151 | }
152 |
153 | public function isReadable()
154 | {
155 | return $this->readable;
156 | }
157 |
158 | public function read($length)
159 | {
160 | if (!$this->readable) {
161 | throw new \RuntimeException('Cannot read from non-readable stream');
162 | }
163 | if ($length < 0) {
164 | throw new \RuntimeException('Length parameter cannot be negative');
165 | }
166 | if (0 === $length) {
167 | return '';
168 | }
169 | $string = fread($this->stream, $length);
170 | if (false === $string) {
171 | throw new \RuntimeException('Unable to read from stream');
172 | }
173 |
174 | return $string;
175 | }
176 |
177 | public function getContents()
178 | {
179 | $contents = stream_get_contents($this->stream);
180 | if ($contents === false) {
181 | throw new \RuntimeException('Unable to read stream contents');
182 | }
183 | return $contents;
184 | }
185 |
186 | public function getMetadata($key = null)
187 | {
188 | if (!$this->stream) {
189 | return $key ? '' : [];
190 | } elseif (!$key) {
191 | return stream_get_meta_data($this->stream);
192 | }
193 | $meta = stream_get_meta_data($this->stream);
194 | return isset($meta[$key]) ? $meta[$key] : null;
195 | }
196 |
197 | public function __destruct()
198 | {
199 | $this->close();
200 | }
201 | }
--------------------------------------------------------------------------------
/src/Core/Lib/Strings.php:
--------------------------------------------------------------------------------
1 |
8 | * @package Core\Lib
9 | */
10 | class Strings
11 | {
12 |
13 | /**
14 | * 生成一个token
15 | *
16 | * @return string
17 | */
18 | public static function makeToken()
19 | {
20 | return md5(uniqid(microtime(true), true));
21 | }
22 |
23 | /**
24 | * 产生随机字符串
25 | *
26 | * @param int $length 长度
27 | * @param string $string 包含的字符列表,必须是ASCII字符
28 | * @return string
29 | */
30 | public static function random($length, $string = '23456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz')
31 | {
32 | return substr(str_shuffle(str_repeat($string, $length < strlen($string) ? 1 : ceil($length / strlen($string)))), 0, $length);
33 | }
34 |
35 | /**
36 | * 字符串截取
37 | *
38 | * @param string $str
39 | * @param int $len
40 | * @param string $dot
41 | * @param string $encoding
42 | * @return string
43 | */
44 | public static function truncate($str, $len = 0, $dot = '...', $encoding = CHARSET)
45 | {
46 | if (!$len || strlen($str) <= $len) return $str;
47 | $tempStr = '';
48 | $pre = $end = chr(1);
49 | $str = str_replace(['&', '"', '<', '>'], [$pre . '&' . $end, $pre . '"' . $end, $pre . '<' . $end, $pre . '>' . $end], $str);
50 | $encoding = strtolower($encoding);
51 | if ($encoding == 'utf-8') {
52 | $n = $tn = $noc = 0;
53 | while ($n < strlen($str)) {
54 | $t = ord($str[$n]);
55 | if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
56 | $tn = 1;
57 | $n++;
58 | $noc++;
59 | } elseif (194 <= $t && $t <= 223) {
60 | $tn = 2;
61 | $n += 2;
62 | $noc += 2;
63 | } elseif (224 <= $t && $t < 239) {
64 | $tn = 3;
65 | $n += 3;
66 | $noc += 2;
67 | } elseif (240 <= $t && $t <= 247) {
68 | $tn = 4;
69 | $n += 4;
70 | $noc += 2;
71 | } elseif (248 <= $t && $t <= 251) {
72 | $tn = 5;
73 | $n += 5;
74 | $noc += 2;
75 | } elseif ($t == 252 || $t == 253) {
76 | $tn = 6;
77 | $n += 6;
78 | $noc += 2;
79 | } else {
80 | $n++;
81 | }
82 | if ($noc >= $len) {
83 | break;
84 | }
85 | }
86 | if ($noc > $len) {
87 | $n -= $tn;
88 | }
89 | $tempStr = substr($str, 0, $n);
90 | } elseif ($encoding == 'gbk') {
91 | for ($i = 0; $i < $len; $i++) {
92 | $tempStr .= ord($str{$i}) > 127 ? $str{$i} . $str{++$i} : $str{$i};
93 | }
94 | }
95 | $tempStr = str_replace([$pre . '&' . $end, $pre . '"' . $end, $pre . '<' . $end, $pre . '>' . $end], ['&', '"', '<', '>'], $tempStr);
96 | return $tempStr . $dot;
97 | }
98 |
99 | /**
100 | * 字符串过滤
101 | *
102 | * @param string $string
103 | * @param boolean $isurl
104 | * @return string
105 | */
106 | public static function safeStr($string, $isurl = false)
107 | {
108 | $string = preg_replace('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '', $string);
109 | $string = str_replace(["\0", "%00", "\r"], '', $string);
110 | empty($isurl) && $string = preg_replace("/&(?!(#[0-9]+|[a-z]+);)/si", '&', $string);
111 | $string = str_replace(["%3C", '<'], '<', $string);
112 | $string = str_replace(["%3E", '>'], '>', $string);
113 | $string = str_replace(['"', "'", "\t", ' '], ['"', ''', ' ', ' '], $string);
114 | return trim($string);
115 | }
116 |
117 | /**
118 | * 数组元素串接
119 | *
120 | * 将数组的每个元素用逗号连接起来,并给每个元素添加单引号,用于SQL语句中串接ID
121 | * @param array $array
122 | * @return string
123 | */
124 | public static function simplode($array)
125 | {
126 | return "'" . implode("','", $array) . "'";
127 | }
128 |
129 | /**
130 | * 为特殊字符加上反斜杠
131 | *
132 | * 与addslashes不同之处在于本函数支持数组
133 | *
134 | * @param string|array $input
135 | * @return string|array 返回处理后的变量
136 | */
137 | public static function addSlashes($input)
138 | {
139 | if (!is_array($input)) return addslashes($input);
140 | foreach ($input as $key => $val) {
141 | $input[$key] = static::addSlashes($val);
142 | }
143 | return $input;
144 | }
145 |
146 | /**
147 | * 去除特殊字符的反斜杠
148 | *
149 | * 与stripslashes不同之处在于本函数支持数组
150 | *
151 | * @param string|array $input
152 | * @return string|array 返回处理后的变量
153 | */
154 | public static function delSlashes($input)
155 | {
156 | if (!is_array($input)) return stripslashes($input);
157 | foreach ($input as $key => $val) {
158 | $input[$key] = static::delSlashes($val);
159 | }
160 | return $input;
161 | }
162 |
163 | /**
164 | * 计算字符串长度,一个汉字为1
165 | *
166 | * @param string $string
167 | * @return int
168 | */
169 | public static function len($string)
170 | {
171 | return mb_strlen($string, CHARSET);
172 | }
173 |
174 | /**
175 | * base64编码为可用于URL参数形式
176 | *
177 | * @param string $string
178 | * @return string
179 | */
180 | public static function base64EncodeURL($string)
181 | {
182 | return str_replace(['+', '/'], ['-', '_'], rtrim(base64_encode($string), '='));
183 | }
184 |
185 | /**
186 | * 解码URL形式base64
187 | *
188 | * @param string $string
189 | * @return string
190 | */
191 | public static function base64DecodeURL($string)
192 | {
193 | return base64_decode(str_replace(['-','_'], ['+', '/'], $string));
194 | }
195 |
196 | /**
197 | * 检查字符串编码是否是UTF8
198 | *
199 | * @param string $value
200 | * @return bool
201 | */
202 | public static function isUTF8($value)
203 | {
204 | return $value === '' || preg_match('/^./su', $value) === 1;
205 | }
206 | }
207 |
--------------------------------------------------------------------------------