| [ Index ] |
|
Code source de GeekLog 1.4.1 |
1 <?php 2 /** 3 * Error Stack Implementation 4 * 5 * This is an incredibly simple implementation of a very complex error handling 6 * facility. It contains the ability 7 * to track multiple errors from multiple packages simultaneously. In addition, 8 * it can track errors of many levels, save data along with the error, context 9 * information such as the exact file, line number, class and function that 10 * generated the error, and if necessary, it can raise a traditional PEAR_Error. 11 * It has built-in support for PEAR::Log, to log errors as they occur 12 * 13 * Since version 0.2alpha, it is also possible to selectively ignore errors, 14 * through the use of an error callback, see {@link pushCallback()} 15 * 16 * Since version 0.3alpha, it is possible to specify the exception class 17 * returned from {@link push()} 18 * 19 * Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can 20 * still be done quite handily in an error callback or by manipulating the returned array 21 * @category Debugging 22 * @package PEAR_ErrorStack 23 * @author Greg Beaver <cellog@php.net> 24 * @copyright 2004-2006 Greg Beaver 25 * @license http://www.php.net/license/3_0.txt PHP License 3.0 26 * @version CVS: $Id: ErrorStack.php,v 1.22 2006/01/06 04:47:36 cellog Exp $ 27 * @link http://pear.php.net/package/PEAR_ErrorStack 28 */ 29 30 /** 31 * Singleton storage 32 * 33 * Format: 34 * <pre> 35 * array( 36 * 'package1' => PEAR_ErrorStack object, 37 * 'package2' => PEAR_ErrorStack object, 38 * ... 39 * ) 40 * </pre> 41 * @access private 42 * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] 43 */ 44 $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array(); 45 46 /** 47 * Global error callback (default) 48 * 49 * This is only used if set to non-false. * is the default callback for 50 * all packages, whereas specific packages may set a default callback 51 * for all instances, regardless of whether they are a singleton or not. 52 * 53 * To exclude non-singletons, only set the local callback for the singleton 54 * @see PEAR_ErrorStack::setDefaultCallback() 55 * @access private 56 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] 57 */ 58 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array( 59 '*' => false, 60 ); 61 62 /** 63 * Global Log object (default) 64 * 65 * This is only used if set to non-false. Use to set a default log object for 66 * all stacks, regardless of instantiation order or location 67 * @see PEAR_ErrorStack::setDefaultLogger() 68 * @access private 69 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] 70 */ 71 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false; 72 73 /** 74 * Global Overriding Callback 75 * 76 * This callback will override any error callbacks that specific loggers have set. 77 * Use with EXTREME caution 78 * @see PEAR_ErrorStack::staticPushCallback() 79 * @access private 80 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] 81 */ 82 $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); 83 84 /**#@+ 85 * One of four possible return values from the error Callback 86 * @see PEAR_ErrorStack::_errorCallback() 87 */ 88 /** 89 * If this is returned, then the error will be both pushed onto the stack 90 * and logged. 91 */ 92 define('PEAR_ERRORSTACK_PUSHANDLOG', 1); 93 /** 94 * If this is returned, then the error will only be pushed onto the stack, 95 * and not logged. 96 */ 97 define('PEAR_ERRORSTACK_PUSH', 2); 98 /** 99 * If this is returned, then the error will only be logged, but not pushed 100 * onto the error stack. 101 */ 102 define('PEAR_ERRORSTACK_LOG', 3); 103 /** 104 * If this is returned, then the error is completely ignored. 105 */ 106 define('PEAR_ERRORSTACK_IGNORE', 4); 107 /** 108 * If this is returned, then the error is logged and die() is called. 109 */ 110 define('PEAR_ERRORSTACK_DIE', 5); 111 /**#@-*/ 112 113 /** 114 * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in 115 * the singleton method. 116 */ 117 define('PEAR_ERRORSTACK_ERR_NONCLASS', 1); 118 119 /** 120 * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()} 121 * that has no __toString() method 122 */ 123 define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2); 124 /** 125 * Error Stack Implementation 126 * 127 * Usage: 128 * <code> 129 * // global error stack 130 * $global_stack = &PEAR_ErrorStack::singleton('MyPackage'); 131 * // local error stack 132 * $local_stack = new PEAR_ErrorStack('MyPackage'); 133 * </code> 134 * @author Greg Beaver <cellog@php.net> 135 * @version 1.4.11 136 * @package PEAR_ErrorStack 137 * @category Debugging 138 * @copyright 2004-2006 Greg Beaver 139 * @license http://www.php.net/license/3_0.txt PHP License 3.0 140 * @version CVS: $Id: ErrorStack.php,v 1.22 2006/01/06 04:47:36 cellog Exp $ 141 * @link http://pear.php.net/package/PEAR_ErrorStack 142 */ 143 class PEAR_ErrorStack { 144 /** 145 * Errors are stored in the order that they are pushed on the stack. 146 * @since 0.4alpha Errors are no longer organized by error level. 147 * This renders pop() nearly unusable, and levels could be more easily 148 * handled in a callback anyway 149 * @var array 150 * @access private 151 */ 152 var $_errors = array(); 153 154 /** 155 * Storage of errors by level. 156 * 157 * Allows easy retrieval and deletion of only errors from a particular level 158 * @since PEAR 1.4.0dev 159 * @var array 160 * @access private 161 */ 162 var $_errorsByLevel = array(); 163 164 /** 165 * Package name this error stack represents 166 * @var string 167 * @access protected 168 */ 169 var $_package; 170 171 /** 172 * Determines whether a PEAR_Error is thrown upon every error addition 173 * @var boolean 174 * @access private 175 */ 176 var $_compat = false; 177 178 /** 179 * If set to a valid callback, this will be used to generate the error 180 * message from the error code, otherwise the message passed in will be 181 * used 182 * @var false|string|array 183 * @access private 184 */ 185 var $_msgCallback = false; 186 187 /** 188 * If set to a valid callback, this will be used to generate the error 189 * context for an error. For PHP-related errors, this will be a file 190 * and line number as retrieved from debug_backtrace(), but can be 191 * customized for other purposes. The error might actually be in a separate 192 * configuration file, or in a database query. 193 * @var false|string|array 194 * @access protected 195 */ 196 var $_contextCallback = false; 197 198 /** 199 * If set to a valid callback, this will be called every time an error 200 * is pushed onto the stack. The return value will be used to determine 201 * whether to allow an error to be pushed or logged. 202 * 203 * The return value must be one an PEAR_ERRORSTACK_* constant 204 * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG 205 * @var false|string|array 206 * @access protected 207 */ 208 var $_errorCallback = array(); 209 210 /** 211 * PEAR::Log object for logging errors 212 * @var false|Log 213 * @access protected 214 */ 215 var $_logger = false; 216 217 /** 218 * Error messages - designed to be overridden 219 * @var array 220 * @abstract 221 */ 222 var $_errorMsgs = array(); 223 224 /** 225 * Set up a new error stack 226 * 227 * @param string $package name of the package this error stack represents 228 * @param callback $msgCallback callback used for error message generation 229 * @param callback $contextCallback callback used for context generation, 230 * defaults to {@link getFileLine()} 231 * @param boolean $throwPEAR_Error 232 */ 233 function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false, 234 $throwPEAR_Error = false) 235 { 236 $this->_package = $package; 237 $this->setMessageCallback($msgCallback); 238 $this->setContextCallback($contextCallback); 239 $this->_compat = $throwPEAR_Error; 240 } 241 242 /** 243 * Return a single error stack for this package. 244 * 245 * Note that all parameters are ignored if the stack for package $package 246 * has already been instantiated 247 * @param string $package name of the package this error stack represents 248 * @param callback $msgCallback callback used for error message generation 249 * @param callback $contextCallback callback used for context generation, 250 * defaults to {@link getFileLine()} 251 * @param boolean $throwPEAR_Error 252 * @param string $stackClass class to instantiate 253 * @static 254 * @return PEAR_ErrorStack 255 */ 256 function &singleton($package, $msgCallback = false, $contextCallback = false, 257 $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack') 258 { 259 if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { 260 return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; 261 } 262 if (!class_exists($stackClass)) { 263 if (function_exists('debug_backtrace')) { 264 $trace = debug_backtrace(); 265 } 266 PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS, 267 'exception', array('stackclass' => $stackClass), 268 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)', 269 false, $trace); 270 } 271 $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] = 272 new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error); 273 274 return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; 275 } 276 277 /** 278 * Internal error handler for PEAR_ErrorStack class 279 * 280 * Dies if the error is an exception (and would have died anyway) 281 * @access private 282 */ 283 function _handleError($err) 284 { 285 if ($err['level'] == 'exception') { 286 $message = $err['message']; 287 if (isset($_SERVER['REQUEST_URI'])) { 288 echo '<br />'; 289 } else { 290 echo "\n"; 291 } 292 var_dump($err['context']); 293 die($message); 294 } 295 } 296 297 /** 298 * Set up a PEAR::Log object for all error stacks that don't have one 299 * @param Log $log 300 * @static 301 */ 302 function setDefaultLogger(&$log) 303 { 304 if (is_object($log) && method_exists($log, 'log') ) { 305 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; 306 } elseif (is_callable($log)) { 307 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; 308 } 309 } 310 311 /** 312 * Set up a PEAR::Log object for this error stack 313 * @param Log $log 314 */ 315 function setLogger(&$log) 316 { 317 if (is_object($log) && method_exists($log, 'log') ) { 318 $this->_logger = &$log; 319 } elseif (is_callable($log)) { 320 $this->_logger = &$log; 321 } 322 } 323 324 /** 325 * Set an error code => error message mapping callback 326 * 327 * This method sets the callback that can be used to generate error 328 * messages for any instance 329 * @param array|string Callback function/method 330 */ 331 function setMessageCallback($msgCallback) 332 { 333 if (!$msgCallback) { 334 $this->_msgCallback = array(&$this, 'getErrorMessage'); 335 } else { 336 if (is_callable($msgCallback)) { 337 $this->_msgCallback = $msgCallback; 338 } 339 } 340 } 341 342 /** 343 * Get an error code => error message mapping callback 344 * 345 * This method returns the current callback that can be used to generate error 346 * messages 347 * @return array|string|false Callback function/method or false if none 348 */ 349 function getMessageCallback() 350 { 351 return $this->_msgCallback; 352 } 353 354 /** 355 * Sets a default callback to be used by all error stacks 356 * 357 * This method sets the callback that can be used to generate error 358 * messages for a singleton 359 * @param array|string Callback function/method 360 * @param string Package name, or false for all packages 361 * @static 362 */ 363 function setDefaultCallback($callback = false, $package = false) 364 { 365 if (!is_callable($callback)) { 366 $callback = false; 367 } 368 $package = $package ? $package : '*'; 369 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback; 370 } 371 372 /** 373 * Set a callback that generates context information (location of error) for an error stack 374 * 375 * This method sets the callback that can be used to generate context 376 * information for an error. Passing in NULL will disable context generation 377 * and remove the expensive call to debug_backtrace() 378 * @param array|string|null Callback function/method 379 */ 380 function setContextCallback($contextCallback) 381 { 382 if ($contextCallback === null) { 383 return $this->_contextCallback = false; 384 } 385 if (!$contextCallback) { 386 $this->_contextCallback = array(&$this, 'getFileLine'); 387 } else { 388 if (is_callable($contextCallback)) { 389 $this->_contextCallback = $contextCallback; 390 } 391 } 392 } 393 394 /** 395 * Set an error Callback 396 * If set to a valid callback, this will be called every time an error 397 * is pushed onto the stack. The return value will be used to determine 398 * whether to allow an error to be pushed or logged. 399 * 400 * The return value must be one of the ERRORSTACK_* constants. 401 * 402 * This functionality can be used to emulate PEAR's pushErrorHandling, and 403 * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of 404 * the error stack or logging 405 * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG 406 * @see popCallback() 407 * @param string|array $cb 408 */ 409 function pushCallback($cb) 410 { 411 array_push($this->_errorCallback, $cb); 412 } 413 414 /** 415 * Remove a callback from the error callback stack 416 * @see pushCallback() 417 * @return array|string|false 418 */ 419 function popCallback() 420 { 421 if (!count($this->_errorCallback)) { 422 return false; 423 } 424 return array_pop($this->_errorCallback); 425 } 426 427 /** 428 * Set a temporary overriding error callback for every package error stack 429 * 430 * Use this to temporarily disable all existing callbacks (can be used 431 * to emulate the @ operator, for instance) 432 * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG 433 * @see staticPopCallback(), pushCallback() 434 * @param string|array $cb 435 * @static 436 */ 437 function staticPushCallback($cb) 438 { 439 array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb); 440 } 441 442 /** 443 * Remove a temporary overriding error callback 444 * @see staticPushCallback() 445 * @return array|string|false 446 * @static 447 */ 448 function staticPopCallback() 449 { 450 $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); 451 if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) { 452 $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); 453 } 454 return $ret; 455 } 456 457 /** 458 * Add an error to the stack 459 * 460 * If the message generator exists, it is called with 2 parameters. 461 * - the current Error Stack object 462 * - an array that is in the same format as an error. Available indices 463 * are 'code', 'package', 'time', 'params', 'level', and 'context' 464 * 465 * Next, if the error should contain context information, this is 466 * handled by the context grabbing method. 467 * Finally, the error is pushed onto the proper error stack 468 * @param int $code Package-specific error code 469 * @param string $level Error level. This is NOT spell-checked 470 * @param array $params associative array of error parameters 471 * @param string $msg Error message, or a portion of it if the message 472 * is to be generated 473 * @param array $repackage If this error re-packages an error pushed by 474 * another package, place the array returned from 475 * {@link pop()} in this parameter 476 * @param array $backtrace Protected parameter: use this to pass in the 477 * {@link debug_backtrace()} that should be used 478 * to find error context 479 * @return PEAR_Error|array|Exception 480 * if compatibility mode is on, a PEAR_Error is also 481 * thrown. If the class Exception exists, then one 482 * is returned to allow code like: 483 * <code> 484 * throw ($stack->push(MY_ERROR_CODE, 'error', array('username' => 'grob'))); 485 * </code> 486 * 487 * The errorData property of the exception class will be set to the array 488 * that would normally be returned. If a PEAR_Error is returned, the userinfo 489 * property is set to the array 490 * 491 * Otherwise, an array is returned in this format: 492 * <code> 493 * array( 494 * 'code' => $code, 495 * 'params' => $params, 496 * 'package' => $this->_package, 497 * 'level' => $level, 498 * 'time' => time(), 499 * 'context' => $context, 500 * 'message' => $msg, 501 * //['repackage' => $err] repackaged error array/Exception class 502 * ); 503 * </code> 504 */ 505 function push($code, $level = 'error', $params = array(), $msg = false, 506 $repackage = false, $backtrace = false) 507 { 508 $context = false; 509 // grab error context 510 if ($this->_contextCallback) { 511 if (!$backtrace) { 512 $backtrace = debug_backtrace(); 513 } 514 $context = call_user_func($this->_contextCallback, $code, $params, $backtrace); 515 } 516 517 // save error 518 $time = explode(' ', microtime()); 519 $time = $time[1] + $time[0]; 520 $err = array( 521 'code' => $code, 522 'params' => $params, 523 'package' => $this->_package, 524 'level' => $level, 525 'time' => $time, 526 'context' => $context, 527 'message' => $msg, 528 ); 529 530 if ($repackage) { 531 $err['repackage'] = $repackage; 532 } 533 534 // set up the error message, if necessary 535 if ($this->_msgCallback) { 536 $msg = call_user_func_array($this->_msgCallback, 537 array(&$this, $err)); 538 $err['message'] = $msg; 539 } 540 $push = $log = true; 541 $die = false; 542 // try the overriding callback first 543 $callback = $this->staticPopCallback(); 544 if ($callback) { 545 $this->staticPushCallback($callback); 546 } 547 if (!is_callable($callback)) { 548 // try the local callback next 549 $callback = $this->popCallback(); 550 if (is_callable($callback)) { 551 $this->pushCallback($callback); 552 } else { 553 // try the default callback 554 $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ? 555 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] : 556 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*']; 557 } 558 } 559 if (is_callable($callback)) { 560 switch(call_user_func($callback, $err)){ 561 case PEAR_ERRORSTACK_IGNORE: 562 return $err; 563 break; 564 case PEAR_ERRORSTACK_PUSH: 565 $log = false; 566 break; 567 case PEAR_ERRORSTACK_LOG: 568 $push = false; 569 break; 570 case PEAR_ERRORSTACK_DIE: 571 $die = true; 572 break; 573 // anything else returned has the same effect as pushandlog 574 } 575 } 576 if ($push) { 577 array_unshift($this->_errors, $err); 578 $this->_errorsByLevel[$err['level']][] = &$this->_errors[0]; 579 } 580 if ($log) { 581 if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) { 582 $this->_log($err); 583 } 584 } 585 if ($die) { 586 die(); 587 } 588 if ($this->_compat && $push) { 589 return $this->raiseError($msg, $code, null, null, $err); 590 } 591 return $err; 592 } 593 594 /** 595 * Static version of {@link push()} 596 * 597 * @param string $package Package name this error belongs to 598 * @param int $code Package-specific error code 599 * @param string $level Error level. This is NOT spell-checked 600 * @param array $params associative array of error parameters 601 * @param string $msg Error message, or a portion of it if the message 602 * is to be generated 603 * @param array $repackage If this error re-packages an error pushed by 604 * another package, place the array returned from 605 * {@link pop()} in this parameter 606 * @param array $backtrace Protected parameter: use this to pass in the 607 * {@link debug_backtrace()} that should be used 608 * to find error context 609 * @return PEAR_Error|null|Exception 610 * if compatibility mode is on, a PEAR_Error is also 611 * thrown. If the class Exception exists, then one 612 * is returned to allow code like: 613 * <code> 614 * throw ($stack->push(MY_ERROR_CODE, 'error', array('username' => 'grob'))); 615 * </code> 616 * @static 617 */ 618 function staticPush($package, $code, $level = 'error', $params = array(), 619 $msg = false, $repackage = false, $backtrace = false) 620 { 621 $s = &PEAR_ErrorStack::singleton($package); 622 if ($s->_contextCallback) { 623 if (!$backtrace) { 624 if (function_exists('debug_backtrace')) { 625 $backtrace = debug_backtrace(); 626 } 627 } 628 } 629 return $s->push($code, $level, $params, $msg, $repackage, $backtrace); 630 } 631 632 /** 633 * Log an error using PEAR::Log 634 * @param array $err Error array 635 * @param array $levels Error level => Log constant map 636 * @access protected 637 */ 638 function _log($err) 639 { 640 if ($this->_logger) { 641 $logger = &$this->_logger; 642 } else { 643 $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']; 644 } 645 if (is_a($logger, 'Log')) { 646 $levels = array( 647 'exception' => PEAR_LOG_CRIT, 648 'alert' => PEAR_LOG_ALERT, 649 'critical' => PEAR_LOG_CRIT, 650 'error' => PEAR_LOG_ERR, 651 'warning' => PEAR_LOG_WARNING, 652 'notice' => PEAR_LOG_NOTICE, 653 'info' => PEAR_LOG_INFO, 654 'debug' => PEAR_LOG_DEBUG); 655 if (isset($levels[$err['level']])) { 656 $level = $levels[$err['level']]; 657 } else { 658 $level = PEAR_LOG_INFO; 659 } 660 $logger->log($err['message'], $level, $err); 661 } else { // support non-standard logs 662 call_user_func($logger, $err); 663 } 664 } 665 666 667 /** 668 * Pop an error off of the error stack 669 * 670 * @return false|array 671 * @since 0.4alpha it is no longer possible to specify a specific error 672 * level to return - the last error pushed will be returned, instead 673 */ 674 function pop() 675 { 676 return @array_shift($this->_errors); 677 } 678 679 /** 680 * Determine whether there are any errors on the stack 681 * @param string|array Level name. Use to determine if any errors 682 * of level (string), or levels (array) have been pushed 683 * @return boolean 684 */ 685 function hasErrors($level = false) 686 { 687 if ($level) { 688 return isset($this->_errorsByLevel[$level]); 689 } 690 return count($this->_errors); 691 } 692 693 /** 694 * Retrieve all errors since last purge 695 * 696 * @param boolean set in order to empty the error stack 697 * @param string level name, to return only errors of a particular severity 698 * @return array 699 */ 700 function getErrors($purge = false, $level = false) 701 { 702 if (!$purge) { 703 if ($level) { 704 if (!isset($this->_errorsByLevel[$level])) { 705 return array(); 706 } else { 707 return $this->_errorsByLevel[$level]; 708 } 709 } else { 710 return $this->_errors; 711 } 712 } 713 if ($level) { 714 $ret = $this->_errorsByLevel[$level]; 715 foreach ($this->_errorsByLevel[$level] as $i => $unused) { 716 // entries are references to the $_errors array 717 $this->_errorsByLevel[$level][$i] = false; 718 } 719 // array_filter removes all entries === false 720 $this->_errors = array_filter($this->_errors); 721 unset($this->_errorsByLevel[$level]); 722 return $ret; 723 } 724 $ret = $this->_errors; 725 $this->_errors = array(); 726 $this->_errorsByLevel = array(); 727 return $ret; 728 } 729 730 /** 731 * Determine whether there are any errors on a single error stack, or on any error stack 732 * 733 * The optional parameter can be used to test the existence of any errors without the need of 734 * singleton instantiation 735 * @param string|false Package name to check for errors 736 * @param string Level name to check for a particular severity 737 * @return boolean 738 * @static 739 */ 740 function staticHasErrors($package = false, $level = false) 741 { 742 if ($package) { 743 if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { 744 return false; 745 } 746 return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level); 747 } 748 foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { 749 if ($obj->hasErrors($level)) { 750 return true; 751 } 752 } 753 return false; 754 } 755 756 /** 757 * Get a list of all errors since last purge, organized by package 758 * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be 759 * @param boolean $purge Set to purge the error stack of existing errors 760 * @param string $level Set to a level name in order to retrieve only errors of a particular level 761 * @param boolean $merge Set to return a flat array, not organized by package 762 * @param array $sortfunc Function used to sort a merged array - default 763 * sorts by time, and should be good for most cases 764 * @static 765 * @return array 766 */ 767 function staticGetErrors($purge = false, $level = false, $merge = false, 768 $sortfunc = array('PEAR_ErrorStack', '_sortErrors')) 769 { 770 $ret = array(); 771 if (!is_callable($sortfunc)) { 772 $sortfunc = array('PEAR_ErrorStack', '_sortErrors'); 773 } 774 foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { 775 $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level); 776 if ($test) { 777 if ($merge) { 778 $ret = array_merge($ret, $test); 779 } else { 780 $ret[$package] = $test; 781 } 782 } 783 } 784 if ($merge) { 785 usort($ret, $sortfunc); 786 } 787 return $ret; 788 } 789 790 /** 791 * Error sorting function, sorts by time 792 * @access private 793 */ 794 function _sortErrors($a, $b) 795 { 796 if ($a['time'] == $b['time']) { 797 return 0; 798 } 799 if ($a['time'] < $b['time']) { 800 return 1; 801 } 802 return -1; 803 } 804 805 /** 806 * Standard file/line number/function/class context callback 807 * 808 * This function uses a backtrace generated from {@link debug_backtrace()} 809 * and so will not work at all in PHP < 4.3.0. The frame should 810 * reference the frame that contains the source of the error. 811 * @return array|false either array('file' => file, 'line' => line, 812 * 'function' => function name, 'class' => class name) or 813 * if this doesn't work, then false 814 * @param unused 815 * @param integer backtrace frame. 816 * @param array Results of debug_backtrace() 817 * @static 818 */ 819 function getFileLine($code, $params, $backtrace = null) 820 { 821 if ($backtrace === null) { 822 return false; 823 } 824 $frame = 0; 825 $functionframe = 1; 826 if (!isset($backtrace[1])) { 827 $functionframe = 0; 828 } else { 829 while (isset($backtrace[$functionframe]['function']) && 830 $backtrace[$functionframe]['function'] == 'eval' && 831 isset($backtrace[$functionframe + 1])) { 832 $functionframe++; 833 } 834 } 835 if (isset($backtrace[$frame])) { 836 if (!isset($backtrace[$frame]['file'])) { 837 $frame++; 838 } 839 $funcbacktrace = $backtrace[$functionframe]; 840 $filebacktrace = $backtrace[$frame]; 841 $ret = array('file' => $filebacktrace['file'], 842 'line' => $filebacktrace['line']); 843 // rearrange for eval'd code or create function errors 844 if (strpos($filebacktrace['file'], '(') && 845 preg_match(';^(.*?)\((\d+)\) : (.*?)$;', $filebacktrace['file'], 846 $matches)) { 847 $ret['file'] = $matches[1]; 848 $ret['line'] = $matches[2] + 0; 849 } 850 if (isset($funcbacktrace['function']) && isset($backtrace[1])) { 851 if ($funcbacktrace['function'] != 'eval') { 852 if ($funcbacktrace['function'] == '__lambda_func') { 853 $ret['function'] = 'create_function() code'; 854 } else { 855 $ret['function'] = $funcbacktrace['function']; 856 } 857 } 858 } 859 if (isset($funcbacktrace['class']) && isset($backtrace[1])) { 860 $ret['class'] = $funcbacktrace['class']; 861 } 862 return $ret; 863 } 864 return false; 865 } 866 867 /** 868 * Standard error message generation callback 869 * 870 * This method may also be called by a custom error message generator 871 * to fill in template values from the params array, simply 872 * set the third parameter to the error message template string to use 873 * 874 * The special variable %__msg% is reserved: use it only to specify 875 * where a message passed in by the user should be placed in the template, 876 * like so: 877 * 878 * Error message: %msg% - internal error 879 * 880 * If the message passed like so: 881 * 882 * <code> 883 * $stack->push(ERROR_CODE, 'error', array(), 'server error 500'); 884 * </code> 885 * 886 * The returned error message will be "Error message: server error 500 - 887 * internal error" 888 * @param PEAR_ErrorStack 889 * @param array 890 * @param string|false Pre-generated error message template 891 * @static 892 * @return string 893 */ 894 function getErrorMessage(&$stack, $err, $template = false) 895 { 896 if ($template) { 897 $mainmsg = $template; 898 } else { 899 $mainmsg = $stack->getErrorMessageTemplate($err['code']); 900 } 901 $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg); 902 if (is_array($err['params']) && count($err['params'])) { 903 foreach ($err['params'] as $name => $val) { 904 if (is_array($val)) { 905 // @ is needed in case $val is a multi-dimensional array 906 $val = @implode(', ', $val); 907 } 908 if (is_object($val)) { 909 if (method_exists($val, '__toString')) { 910 $val = $val->__toString(); 911 } else { 912 PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING, 913 'warning', array('obj' => get_class($val)), 914 'object %obj% passed into getErrorMessage, but has no __toString() method'); 915 $val = 'Object'; 916 } 917 } 918 $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg); 919 } 920 } 921 return $mainmsg; 922 } 923 924 /** 925 * Standard Error Message Template generator from code 926 * @return string 927 */ 928 function getErrorMessageTemplate($code) 929 { 930 if (!isset($this->_errorMsgs[$code])) { 931 return '%__msg%'; 932 } 933 return $this->_errorMsgs[$code]; 934 } 935 936 /** 937 * Set the Error Message Template array 938 * 939 * The array format must be: 940 * <pre> 941 * array(error code => 'message template',...) 942 * </pre> 943 * 944 * Error message parameters passed into {@link push()} will be used as input 945 * for the error message. If the template is 'message %foo% was %bar%', and the 946 * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will 947 * be 'message one was six' 948 * @return string 949 */ 950 function setErrorMessageTemplate($template) 951 { 952 $this->_errorMsgs = $template; 953 } 954 955 956 /** 957 * emulate PEAR::raiseError() 958 * 959 * @return PEAR_Error 960 */ 961 function raiseError() 962 { 963 require_once 'PEAR.php'; 964 $args = func_get_args(); 965 return call_user_func_array(array('PEAR', 'raiseError'), $args); 966 } 967 } 968 $stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack'); 969 $stack->pushCallback(array('PEAR_ErrorStack', '_handleError')); 970 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Wed Nov 21 12:27:40 2007 | par Balluche grâce à PHPXref 0.7 |
|