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