Bearsampp 2026.9.23
Loading...
Searching...
No Matches
Exception.php
Go to the documentation of this file.
1<?php
2/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
19
20
96class PEAR_Exception extends Exception
97{
98 const OBSERVER_PRINT = -2;
99 const OBSERVER_TRIGGER = -4;
100 const OBSERVER_DIE = -8;
101 protected $cause;
102 private static $_observers = array();
103 private static $_uniqueid = 0;
104 private $_trace;
105
120 public function __construct($message, $p2 = null, $p3 = null)
121 {
122 if (is_int($p2)) {
123 $code = $p2;
124 $this->cause = null;
125 } elseif (is_object($p2) || is_array($p2)) {
126 // using is_object allows both Exception and PEAR_Error
127 if (is_object($p2) && !($p2 instanceof Exception)) {
128 if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
129 throw new PEAR_Exception('exception cause must be Exception, ' .
130 'array, or PEAR_Error');
131 }
132 }
133 $code = $p3;
134 if (is_array($p2) && isset($p2['message'])) {
135 // fix potential problem of passing in a single warning
136 $p2 = array($p2);
137 }
138 $this->cause = $p2;
139 } else {
140 $code = null;
141 $this->cause = null;
142 }
143 parent::__construct($message, $code);
144 $this->signal();
145 }
146
155 public static function addObserver($callback, $label = 'default')
156 {
157 self::$_observers[$label] = $callback;
158 }
159
160 public static function removeObserver($label = 'default')
161 {
162 unset(self::$_observers[$label]);
163 }
164
168 public static function getUniqueId()
169 {
170 return self::$_uniqueid++;
171 }
172
173 private function signal()
174 {
175 foreach (self::$_observers as $func) {
176 if (is_callable($func)) {
177 call_user_func($func, $this);
178 continue;
179 }
180 settype($func, 'array');
181 switch ($func[0]) {
182 case self::OBSERVER_PRINT :
183 $f = (isset($func[1])) ? $func[1] : '%s';
184 printf($f, $this->getMessage());
185 break;
186 case self::OBSERVER_TRIGGER :
187 $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE;
188 trigger_error($this->getMessage(), $f);
189 break;
190 case self::OBSERVER_DIE :
191 $f = (isset($func[1])) ? $func[1] : '%s';
192 die(printf($f, $this->getMessage()));
193 break;
194 default:
195 trigger_error('invalid observer type', E_USER_WARNING);
196 }
197 }
198 }
199
214 public function getErrorData()
215 {
216 return array();
217 }
218
224 public function getCause()
225 {
226 return $this->cause;
227 }
228
233 public function getCauseMessage(&$causes)
234 {
235 $trace = $this->getTraceSafe();
236 $cause = array('class' => get_class($this),
237 'message' => $this->message,
238 'file' => 'unknown',
239 'line' => 'unknown');
240 if (isset($trace[0])) {
241 if (isset($trace[0]['file'])) {
242 $cause['file'] = $trace[0]['file'];
243 $cause['line'] = $trace[0]['line'];
244 }
245 }
246 $causes[] = $cause;
247 if ($this->cause instanceof PEAR_Exception) {
248 $this->cause->getCauseMessage($causes);
249 } elseif ($this->cause instanceof Exception) {
250 $causes[] = array('class' => get_class($this->cause),
251 'message' => $this->cause->getMessage(),
252 'file' => $this->cause->getFile(),
253 'line' => $this->cause->getLine());
254 } elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) {
255 $causes[] = array('class' => get_class($this->cause),
256 'message' => $this->cause->getMessage(),
257 'file' => 'unknown',
258 'line' => 'unknown');
259 } elseif (is_array($this->cause)) {
260 foreach ($this->cause as $cause) {
261 if ($cause instanceof PEAR_Exception) {
262 $cause->getCauseMessage($causes);
263 } elseif ($cause instanceof Exception) {
264 $causes[] = array('class' => get_class($cause),
265 'message' => $cause->getMessage(),
266 'file' => $cause->getFile(),
267 'line' => $cause->getLine());
268 } elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) {
269 $causes[] = array('class' => get_class($cause),
270 'message' => $cause->getMessage(),
271 'file' => 'unknown',
272 'line' => 'unknown');
273 } elseif (is_array($cause) && isset($cause['message'])) {
274 // PEAR_ErrorStack warning
275 $causes[] = array(
276 'class' => $cause['package'],
277 'message' => $cause['message'],
278 'file' => isset($cause['context']['file']) ?
279 $cause['context']['file'] :
280 'unknown',
281 'line' => isset($cause['context']['line']) ?
282 $cause['context']['line'] :
283 'unknown',
284 );
285 }
286 }
287 }
288 }
289
290 public function getTraceSafe()
291 {
292 if (!isset($this->_trace)) {
293 $this->_trace = $this->getTrace();
294 if (empty($this->_trace)) {
295 $backtrace = debug_backtrace();
296 $this->_trace = array($backtrace[count($backtrace)-1]);
297 }
298 }
299 return $this->_trace;
300 }
301
302 public function getErrorClass()
303 {
304 $trace = $this->getTraceSafe();
305 return $trace[0]['class'];
306 }
307
308 public function getErrorMethod()
309 {
310 $trace = $this->getTraceSafe();
311 return $trace[0]['function'];
312 }
313
314 public function __toString()
315 {
316 if (isset($_SERVER['REQUEST_URI'])) {
317 return $this->toHtml();
318 }
319 return $this->toText();
320 }
321
322 public function toHtml()
323 {
324 $trace = $this->getTraceSafe();
325 $causes = array();
326 $this->getCauseMessage($causes);
327 $html = '<table style="border: 1px" cellspacing="0">' . "\n";
328 foreach ($causes as $i => $cause) {
329 $html .= '<tr><td colspan="3" style="background: #ff9999">'
330 . str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
331 . htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
332 . 'on line <b>' . $cause['line'] . '</b>'
333 . "</td></tr>\n";
334 }
335 $html .= '<tr><td colspan="3" style="background-color: #aaaaaa; text-align: center; font-weight: bold;">Exception trace</td></tr>' . "\n"
336 . '<tr><td style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>'
337 . '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>'
338 . '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n";
339
340 foreach ($trace as $k => $v) {
341 $html .= '<tr><td style="text-align: center;">' . $k . '</td>'
342 . '<td>';
343 if (!empty($v['class'])) {
344 $html .= $v['class'] . $v['type'];
345 }
346 $html .= $v['function'];
347 $args = array();
348 if (!empty($v['args'])) {
349 foreach ($v['args'] as $arg) {
350 if (is_null($arg)) $args[] = 'null';
351 elseif (is_array($arg)) $args[] = 'Array';
352 elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')';
353 elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false';
354 elseif (is_int($arg) || is_double($arg)) $args[] = $arg;
355 else {
356 $arg = (string)$arg;
357 $str = htmlspecialchars(substr($arg, 0, 16));
358 if (strlen($arg) > 16) $str .= '&hellip;';
359 $args[] = "'" . $str . "'";
360 }
361 }
362 }
363 $html .= '(' . implode(', ',$args) . ')'
364 . '</td>'
365 . '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
366 . ':' . (isset($v['line']) ? $v['line'] : 'unknown')
367 . '</td></tr>' . "\n";
368 }
369 $html .= '<tr><td style="text-align: center;">' . ($k+1) . '</td>'
370 . '<td>{main}</td>'
371 . '<td>&nbsp;</td></tr>' . "\n"
372 . '</table>';
373 return $html;
374 }
375
376 public function toText()
377 {
378 $causes = array();
379 $this->getCauseMessage($causes);
380 $causeMsg = '';
381 foreach ($causes as $i => $cause) {
382 $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': '
383 . $cause['message'] . ' in ' . $cause['file']
384 . ' on line ' . $cause['line'] . "\n";
385 }
386 return $causeMsg . $this->getTraceAsString();
387 }
388}
getCauseMessage(&$causes)
static getUniqueId()
static $_observers
static addObserver($callback, $label='default')
const OBSERVER_PRINT
Definition Exception.php:98
const OBSERVER_TRIGGER
Definition Exception.php:99
__construct($message, $p2=null, $p3=null)
static removeObserver($label='default')
static $_uniqueid