See Release Notes
Long Term Support Release
Differences Between: [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 /** 3 * PEAR, the PHP Extension and Application Repository 4 * 5 * PEAR class and PEAR_Error class 6 * 7 * PHP versions 4 and 5 8 * 9 * @category pear 10 * @package PEAR 11 * @author Sterling Hughes <sterling@php.net> 12 * @author Stig Bakken <ssb@php.net> 13 * @author Tomas V.V.Cox <cox@idecnet.com> 14 * @author Greg Beaver <cellog@php.net> 15 * @copyright 1997-2010 The Authors 16 * @license http://opensource.org/licenses/bsd-license.php New BSD License 17 * @version CVS: $Id$ 18 * @link http://pear.php.net/package/PEAR 19 * @since File available since Release 0.1 20 */ 21 22 /**#@+ 23 * ERROR constants 24 */ 25 define('PEAR_ERROR_RETURN', 1); 26 define('PEAR_ERROR_PRINT', 2); 27 define('PEAR_ERROR_TRIGGER', 4); 28 define('PEAR_ERROR_DIE', 8); 29 define('PEAR_ERROR_CALLBACK', 16); 30 /** 31 * WARNING: obsolete 32 * @deprecated 33 */ 34 define('PEAR_ERROR_EXCEPTION', 32); 35 /**#@-*/ 36 define('PEAR_ZE2', (function_exists('version_compare') && 37 version_compare(zend_version(), "2-dev", "ge"))); 38 39 if (substr(PHP_OS, 0, 3) == 'WIN') { 40 define('OS_WINDOWS', true); 41 define('OS_UNIX', false); 42 define('PEAR_OS', 'Windows'); 43 } else { 44 define('OS_WINDOWS', false); 45 define('OS_UNIX', true); 46 define('PEAR_OS', 'Unix'); // blatant assumption 47 } 48 49 $GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; 50 $GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; 51 $GLOBALS['_PEAR_destructor_object_list'] = array(); 52 $GLOBALS['_PEAR_shutdown_funcs'] = array(); 53 $GLOBALS['_PEAR_error_handler_stack'] = array(); 54 55 @ini_set('track_errors', true); 56 57 /** 58 * Base class for other PEAR classes. Provides rudimentary 59 * emulation of destructors. 60 * 61 * If you want a destructor in your class, inherit PEAR and make a 62 * destructor method called _yourclassname (same name as the 63 * constructor, but with a "_" prefix). Also, in your constructor you 64 * have to call the PEAR constructor: $this->PEAR();. 65 * The destructor method will be called without parameters. Note that 66 * at in some SAPI implementations (such as Apache), any output during 67 * the request shutdown (in which destructors are called) seems to be 68 * discarded. If you need to get any debug information from your 69 * destructor, use error_log(), syslog() or something similar. 70 * 71 * IMPORTANT! To use the emulated destructors you need to create the 72 * objects by reference: $obj =& new PEAR_child; 73 * 74 * @category pear 75 * @package PEAR 76 * @author Stig Bakken <ssb@php.net> 77 * @author Tomas V.V. Cox <cox@idecnet.com> 78 * @author Greg Beaver <cellog@php.net> 79 * @copyright 1997-2006 The PHP Group 80 * @license http://opensource.org/licenses/bsd-license.php New BSD License 81 * @version Release: 1.9.1 82 * @link http://pear.php.net/package/PEAR 83 * @see PEAR_Error 84 * @since Class available since PHP 4.0.2 85 * @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear 86 */ 87 class PEAR 88 { 89 /** 90 * Whether to enable internal debug messages. 91 * 92 * @var bool 93 * @access private 94 */ 95 var $_debug = false; 96 97 /** 98 * Default error mode for this object. 99 * 100 * @var int 101 * @access private 102 */ 103 var $_default_error_mode = null; 104 105 /** 106 * Default error options used for this object when error mode 107 * is PEAR_ERROR_TRIGGER. 108 * 109 * @var int 110 * @access private 111 */ 112 var $_default_error_options = null; 113 114 /** 115 * Default error handler (callback) for this object, if error mode is 116 * PEAR_ERROR_CALLBACK. 117 * 118 * @var string 119 * @access private 120 */ 121 var $_default_error_handler = ''; 122 123 /** 124 * Which class to use for error objects. 125 * 126 * @var string 127 * @access private 128 */ 129 var $_error_class = 'PEAR_Error'; 130 131 /** 132 * An array of expected errors. 133 * 134 * @var array 135 * @access private 136 */ 137 var $_expected_errors = array(); 138 139 /** 140 * Constructor. Registers this object in 141 * $_PEAR_destructor_object_list for destructor emulation if a 142 * destructor object exists. 143 * 144 * @param string $error_class (optional) which class to use for 145 * error objects, defaults to PEAR_Error. 146 * @access public 147 * @return void 148 */ 149 function __construct($error_class = null) 150 { 151 $classname = strtolower(get_class($this)); 152 if ($this->_debug) { 153 print "PEAR constructor called, class=$classname\n"; 154 } 155 156 if ($error_class !== null) { 157 $this->_error_class = $error_class; 158 } 159 160 while ($classname && strcasecmp($classname, "pear")) { 161 $destructor = "_$classname"; 162 if (method_exists($this, $destructor)) { 163 global $_PEAR_destructor_object_list; 164 $_PEAR_destructor_object_list[] = &$this; 165 if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { 166 register_shutdown_function("_PEAR_call_destructors"); 167 $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; 168 } 169 break; 170 } else { 171 $classname = get_parent_class($classname); 172 } 173 } 174 } 175 176 /** 177 * Only here for backwards compatibility. 178 * E.g. Archive_Tar calls $this->PEAR() in its constructor. 179 * 180 * @param string $error_class Which class to use for error objects, 181 * defaults to PEAR_Error. 182 */ 183 public function PEAR($error_class = null) 184 { 185 $this->__construct($error_class); 186 } 187 188 /** 189 * Destructor (the emulated type of...). Does nothing right now, 190 * but is included for forward compatibility, so subclass 191 * destructors should always call it. 192 * 193 * See the note in the class desciption about output from 194 * destructors. 195 * 196 * @access public 197 * @return void 198 */ 199 function _PEAR() { 200 if ($this->_debug) { 201 printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); 202 } 203 } 204 205 /** 206 * If you have a class that's mostly/entirely static, and you need static 207 * properties, you can use this method to simulate them. Eg. in your method(s) 208 * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); 209 * You MUST use a reference, or they will not persist! 210 * 211 * @access public 212 * @param string $class The calling classname, to prevent clashes 213 * @param string $var The variable to retrieve. 214 * @return mixed A reference to the variable. If not set it will be 215 * auto initialised to NULL. 216 */ 217 function &getStaticProperty($class, $var) 218 { 219 static $properties; 220 if (!isset($properties[$class])) { 221 $properties[$class] = array(); 222 } 223 224 if (!array_key_exists($var, $properties[$class])) { 225 $properties[$class][$var] = null; 226 } 227 228 return $properties[$class][$var]; 229 } 230 231 /** 232 * Use this function to register a shutdown method for static 233 * classes. 234 * 235 * @access public 236 * @param mixed $func The function name (or array of class/method) to call 237 * @param mixed $args The arguments to pass to the function 238 * @return void 239 */ 240 function registerShutdownFunc($func, $args = array()) 241 { 242 // if we are called statically, there is a potential 243 // that no shutdown func is registered. Bug #6445 244 if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { 245 register_shutdown_function("_PEAR_call_destructors"); 246 $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; 247 } 248 $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); 249 } 250 251 /** 252 * Tell whether a value is a PEAR error. 253 * 254 * @param mixed $data the value to test 255 * @param int $code if $data is an error object, return true 256 * only if $code is a string and 257 * $obj->getMessage() == $code or 258 * $code is an integer and $obj->getCode() == $code 259 * @access public 260 * @return bool true if parameter is an error 261 */ 262 function isError($data, $code = null) 263 { 264 if (!is_a($data, 'PEAR_Error')) { 265 return false; 266 } 267 268 if (is_null($code)) { 269 return true; 270 } elseif (is_string($code)) { 271 return $data->getMessage() == $code; 272 } 273 274 return $data->getCode() == $code; 275 } 276 277 /** 278 * Sets how errors generated by this object should be handled. 279 * Can be invoked both in objects and statically. If called 280 * statically, setErrorHandling sets the default behaviour for all 281 * PEAR objects. If called in an object, setErrorHandling sets 282 * the default behaviour for that object. 283 * 284 * @param int $mode 285 * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, 286 * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, 287 * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. 288 * 289 * @param mixed $options 290 * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one 291 * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). 292 * 293 * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected 294 * to be the callback function or method. A callback 295 * function is a string with the name of the function, a 296 * callback method is an array of two elements: the element 297 * at index 0 is the object, and the element at index 1 is 298 * the name of the method to call in the object. 299 * 300 * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is 301 * a printf format string used when printing the error 302 * message. 303 * 304 * @access public 305 * @return void 306 * @see PEAR_ERROR_RETURN 307 * @see PEAR_ERROR_PRINT 308 * @see PEAR_ERROR_TRIGGER 309 * @see PEAR_ERROR_DIE 310 * @see PEAR_ERROR_CALLBACK 311 * @see PEAR_ERROR_EXCEPTION 312 * 313 * @since PHP 4.0.5 314 */ 315 function setErrorHandling($mode = null, $options = null) 316 { 317 if (isset($this) && is_a($this, 'PEAR')) { 318 $setmode = &$this->_default_error_mode; 319 $setoptions = &$this->_default_error_options; 320 } else { 321 $setmode = &$GLOBALS['_PEAR_default_error_mode']; 322 $setoptions = &$GLOBALS['_PEAR_default_error_options']; 323 } 324 325 switch ($mode) { 326 case PEAR_ERROR_EXCEPTION: 327 case PEAR_ERROR_RETURN: 328 case PEAR_ERROR_PRINT: 329 case PEAR_ERROR_TRIGGER: 330 case PEAR_ERROR_DIE: 331 case null: 332 $setmode = $mode; 333 $setoptions = $options; 334 break; 335 336 case PEAR_ERROR_CALLBACK: 337 $setmode = $mode; 338 // class/object method callback 339 if (is_callable($options)) { 340 $setoptions = $options; 341 } else { 342 trigger_error("invalid error callback", E_USER_WARNING); 343 } 344 break; 345 346 default: 347 trigger_error("invalid error mode", E_USER_WARNING); 348 break; 349 } 350 } 351 352 /** 353 * This method is used to tell which errors you expect to get. 354 * Expected errors are always returned with error mode 355 * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, 356 * and this method pushes a new element onto it. The list of 357 * expected errors are in effect until they are popped off the 358 * stack with the popExpect() method. 359 * 360 * Note that this method can not be called statically 361 * 362 * @param mixed $code a single error code or an array of error codes to expect 363 * 364 * @return int the new depth of the "expected errors" stack 365 * @access public 366 */ 367 function expectError($code = '*') 368 { 369 if (is_array($code)) { 370 array_push($this->_expected_errors, $code); 371 } else { 372 array_push($this->_expected_errors, array($code)); 373 } 374 return count($this->_expected_errors); 375 } 376 377 /** 378 * This method pops one element off the expected error codes 379 * stack. 380 * 381 * @return array the list of error codes that were popped 382 */ 383 function popExpect() 384 { 385 return array_pop($this->_expected_errors); 386 } 387 388 /** 389 * This method checks unsets an error code if available 390 * 391 * @param mixed error code 392 * @return bool true if the error code was unset, false otherwise 393 * @access private 394 * @since PHP 4.3.0 395 */ 396 function _checkDelExpect($error_code) 397 { 398 $deleted = false; 399 foreach ($this->_expected_errors as $key => $error_array) { 400 if (in_array($error_code, $error_array)) { 401 unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); 402 $deleted = true; 403 } 404 405 // clean up empty arrays 406 if (0 == count($this->_expected_errors[$key])) { 407 unset($this->_expected_errors[$key]); 408 } 409 } 410 411 return $deleted; 412 } 413 414 /** 415 * This method deletes all occurences of the specified element from 416 * the expected error codes stack. 417 * 418 * @param mixed $error_code error code that should be deleted 419 * @return mixed list of error codes that were deleted or error 420 * @access public 421 * @since PHP 4.3.0 422 */ 423 function delExpect($error_code) 424 { 425 $deleted = false; 426 if ((is_array($error_code) && (0 != count($error_code)))) { 427 // $error_code is a non-empty array here; we walk through it trying 428 // to unset all values 429 foreach ($error_code as $key => $error) { 430 $deleted = $this->_checkDelExpect($error) ? true : false; 431 } 432 433 return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME 434 } elseif (!empty($error_code)) { 435 // $error_code comes alone, trying to unset it 436 if ($this->_checkDelExpect($error_code)) { 437 return true; 438 } 439 440 return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME 441 } 442 443 // $error_code is empty 444 return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME 445 } 446 447 /** 448 * This method is a wrapper that returns an instance of the 449 * configured error class with this object's default error 450 * handling applied. If the $mode and $options parameters are not 451 * specified, the object's defaults are used. 452 * 453 * @param mixed $message a text error message or a PEAR error object 454 * 455 * @param int $code a numeric error code (it is up to your class 456 * to define these if you want to use codes) 457 * 458 * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, 459 * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, 460 * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. 461 * 462 * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter 463 * specifies the PHP-internal error level (one of 464 * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). 465 * If $mode is PEAR_ERROR_CALLBACK, this 466 * parameter specifies the callback function or 467 * method. In other error modes this parameter 468 * is ignored. 469 * 470 * @param string $userinfo If you need to pass along for example debug 471 * information, this parameter is meant for that. 472 * 473 * @param string $error_class The returned error object will be 474 * instantiated from this class, if specified. 475 * 476 * @param bool $skipmsg If true, raiseError will only pass error codes, 477 * the error message parameter will be dropped. 478 * 479 * @access public 480 * @return object a PEAR error object 481 * @see PEAR::setErrorHandling 482 * @since PHP 4.0.5 483 */ 484 function &raiseError($message = null, 485 $code = null, 486 $mode = null, 487 $options = null, 488 $userinfo = null, 489 $error_class = null, 490 $skipmsg = false) 491 { 492 // The error is yet a PEAR error object 493 if (is_object($message)) { 494 $code = $message->getCode(); 495 $userinfo = $message->getUserInfo(); 496 $error_class = $message->getType(); 497 $message->error_message_prefix = ''; 498 $message = $message->getMessage(); 499 } 500 501 if ( 502 isset($this) && 503 isset($this->_expected_errors) && 504 count($this->_expected_errors) > 0 && 505 count($exp = end($this->_expected_errors)) 506 ) { 507 if ($exp[0] == "*" || 508 (is_int(reset($exp)) && in_array($code, $exp)) || 509 (is_string(reset($exp)) && in_array($message, $exp)) 510 ) { 511 $mode = PEAR_ERROR_RETURN; 512 } 513 } 514 515 // No mode given, try global ones 516 if ($mode === null) { 517 // Class error handler 518 if (isset($this) && isset($this->_default_error_mode)) { 519 $mode = $this->_default_error_mode; 520 $options = $this->_default_error_options; 521 // Global error handler 522 } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { 523 $mode = $GLOBALS['_PEAR_default_error_mode']; 524 $options = $GLOBALS['_PEAR_default_error_options']; 525 } 526 } 527 528 if ($error_class !== null) { 529 $ec = $error_class; 530 } elseif (isset($this) && isset($this->_error_class)) { 531 $ec = $this->_error_class; 532 } else { 533 $ec = 'PEAR_Error'; 534 } 535 536 if (intval(PHP_VERSION) < 5) { 537 // little non-eval hack to fix bug #12147 538 include 'PEAR/FixPHP5PEARWarnings.php'; 539 return $a; 540 } 541 542 if ($skipmsg) { 543 $a = new $ec($code, $mode, $options, $userinfo); 544 } else { 545 $a = new $ec($message, $code, $mode, $options, $userinfo); 546 } 547 548 return $a; 549 } 550 551 /** 552 * Simpler form of raiseError with fewer options. In most cases 553 * message, code and userinfo are enough. 554 * 555 * @param mixed $message a text error message or a PEAR error object 556 * 557 * @param int $code a numeric error code (it is up to your class 558 * to define these if you want to use codes) 559 * 560 * @param string $userinfo If you need to pass along for example debug 561 * information, this parameter is meant for that. 562 * 563 * @access public 564 * @return object a PEAR error object 565 * @see PEAR::raiseError 566 */ 567 function &throwError($message = null, $code = null, $userinfo = null) 568 { 569 if (isset($this) && is_a($this, 'PEAR')) { 570 $a = &$this->raiseError($message, $code, null, null, $userinfo); 571 return $a; 572 } 573 574 $a = &PEAR::raiseError($message, $code, null, null, $userinfo); 575 return $a; 576 } 577 578 function staticPushErrorHandling($mode, $options = null) 579 { 580 $stack = &$GLOBALS['_PEAR_error_handler_stack']; 581 $def_mode = &$GLOBALS['_PEAR_default_error_mode']; 582 $def_options = &$GLOBALS['_PEAR_default_error_options']; 583 $stack[] = array($def_mode, $def_options); 584 switch ($mode) { 585 case PEAR_ERROR_EXCEPTION: 586 case PEAR_ERROR_RETURN: 587 case PEAR_ERROR_PRINT: 588 case PEAR_ERROR_TRIGGER: 589 case PEAR_ERROR_DIE: 590 case null: 591 $def_mode = $mode; 592 $def_options = $options; 593 break; 594 595 case PEAR_ERROR_CALLBACK: 596 $def_mode = $mode; 597 // class/object method callback 598 if (is_callable($options)) { 599 $def_options = $options; 600 } else { 601 trigger_error("invalid error callback", E_USER_WARNING); 602 } 603 break; 604 605 default: 606 trigger_error("invalid error mode", E_USER_WARNING); 607 break; 608 } 609 $stack[] = array($mode, $options); 610 return true; 611 } 612 613 function staticPopErrorHandling() 614 { 615 $stack = &$GLOBALS['_PEAR_error_handler_stack']; 616 $setmode = &$GLOBALS['_PEAR_default_error_mode']; 617 $setoptions = &$GLOBALS['_PEAR_default_error_options']; 618 array_pop($stack); 619 list($mode, $options) = $stack[sizeof($stack) - 1]; 620 array_pop($stack); 621 switch ($mode) { 622 case PEAR_ERROR_EXCEPTION: 623 case PEAR_ERROR_RETURN: 624 case PEAR_ERROR_PRINT: 625 case PEAR_ERROR_TRIGGER: 626 case PEAR_ERROR_DIE: 627 case null: 628 $setmode = $mode; 629 $setoptions = $options; 630 break; 631 632 case PEAR_ERROR_CALLBACK: 633 $setmode = $mode; 634 // class/object method callback 635 if (is_callable($options)) { 636 $setoptions = $options; 637 } else { 638 trigger_error("invalid error callback", E_USER_WARNING); 639 } 640 break; 641 642 default: 643 trigger_error("invalid error mode", E_USER_WARNING); 644 break; 645 } 646 return true; 647 } 648 649 /** 650 * Push a new error handler on top of the error handler options stack. With this 651 * you can easily override the actual error handler for some code and restore 652 * it later with popErrorHandling. 653 * 654 * @param mixed $mode (same as setErrorHandling) 655 * @param mixed $options (same as setErrorHandling) 656 * 657 * @return bool Always true 658 * 659 * @see PEAR::setErrorHandling 660 */ 661 function pushErrorHandling($mode, $options = null) 662 { 663 $stack = &$GLOBALS['_PEAR_error_handler_stack']; 664 if (isset($this) && is_a($this, 'PEAR')) { 665 $def_mode = &$this->_default_error_mode; 666 $def_options = &$this->_default_error_options; 667 } else { 668 $def_mode = &$GLOBALS['_PEAR_default_error_mode']; 669 $def_options = &$GLOBALS['_PEAR_default_error_options']; 670 } 671 $stack[] = array($def_mode, $def_options); 672 673 if (isset($this) && is_a($this, 'PEAR')) { 674 $this->setErrorHandling($mode, $options); 675 } else { 676 PEAR::setErrorHandling($mode, $options); 677 } 678 $stack[] = array($mode, $options); 679 return true; 680 } 681 682 /** 683 * Pop the last error handler used 684 * 685 * @return bool Always true 686 * 687 * @see PEAR::pushErrorHandling 688 */ 689 function popErrorHandling() 690 { 691 $stack = &$GLOBALS['_PEAR_error_handler_stack']; 692 array_pop($stack); 693 list($mode, $options) = $stack[sizeof($stack) - 1]; 694 array_pop($stack); 695 if (isset($this) && is_a($this, 'PEAR')) { 696 $this->setErrorHandling($mode, $options); 697 } else { 698 PEAR::setErrorHandling($mode, $options); 699 } 700 return true; 701 } 702 703 /** 704 * OS independant PHP extension load. Remember to take care 705 * on the correct extension name for case sensitive OSes. 706 * 707 * @param string $ext The extension name 708 * @return bool Success or not on the dl() call 709 */ 710 function loadExtension($ext) 711 { 712 if (extension_loaded($ext)) { 713 return true; 714 } 715 716 // if either returns true dl() will produce a FATAL error, stop that 717 if ( 718 function_exists('dl') === false || 719 ini_get('enable_dl') != 1 || 720 ini_get('safe_mode') == 1 721 ) { 722 return false; 723 } 724 725 if (OS_WINDOWS) { 726 $suffix = '.dll'; 727 } elseif (PHP_OS == 'HP-UX') { 728 $suffix = '.sl'; 729 } elseif (PHP_OS == 'AIX') { 730 $suffix = '.a'; 731 } elseif (PHP_OS == 'OSX') { 732 $suffix = '.bundle'; 733 } else { 734 $suffix = '.so'; 735 } 736 737 return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); 738 } 739 } 740 741 if (PEAR_ZE2) { 742 include_once 'PEAR5.php'; 743 } 744 745 function _PEAR_call_destructors() 746 { 747 global $_PEAR_destructor_object_list; 748 if (is_array($_PEAR_destructor_object_list) && 749 sizeof($_PEAR_destructor_object_list)) 750 { 751 reset($_PEAR_destructor_object_list); 752 if (PEAR_ZE2) { 753 $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo'); 754 } else { 755 $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); 756 } 757 758 if ($destructLifoExists) { 759 $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); 760 } 761 762 foreach ($_PEAR_destructor_object_list as $k => $objref) { 763 $classname = get_class($objref); 764 while ($classname) { 765 $destructor = "_$classname"; 766 if (method_exists($objref, $destructor)) { 767 $objref->$destructor(); 768 break; 769 } else { 770 $classname = get_parent_class($classname); 771 } 772 } 773 } 774 // Empty the object list to ensure that destructors are 775 // not called more than once. 776 $_PEAR_destructor_object_list = array(); 777 } 778 779 // Now call the shutdown functions 780 if ( 781 isset($GLOBALS['_PEAR_shutdown_funcs']) && 782 is_array($GLOBALS['_PEAR_shutdown_funcs']) && 783 !empty($GLOBALS['_PEAR_shutdown_funcs']) 784 ) { 785 foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { 786 call_user_func_array($value[0], $value[1]); 787 } 788 } 789 } 790 791 /** 792 * Standard PEAR error class for PHP 4 793 * 794 * This class is supserseded by {@link PEAR_Exception} in PHP 5 795 * 796 * @category pear 797 * @package PEAR 798 * @author Stig Bakken <ssb@php.net> 799 * @author Tomas V.V. Cox <cox@idecnet.com> 800 * @author Gregory Beaver <cellog@php.net> 801 * @copyright 1997-2006 The PHP Group 802 * @license http://opensource.org/licenses/bsd-license.php New BSD License 803 * @version Release: 1.9.1 804 * @link http://pear.php.net/manual/en/core.pear.pear-error.php 805 * @see PEAR::raiseError(), PEAR::throwError() 806 * @since Class available since PHP 4.0.2 807 */ 808 class PEAR_Error 809 { 810 var $error_message_prefix = ''; 811 var $mode = PEAR_ERROR_RETURN; 812 var $level = E_USER_NOTICE; 813 var $code = -1; 814 var $message = ''; 815 var $userinfo = ''; 816 var $backtrace = null; 817 818 /** 819 * PEAR_Error constructor 820 * 821 * @param string $message message 822 * 823 * @param int $code (optional) error code 824 * 825 * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, 826 * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, 827 * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION 828 * 829 * @param mixed $options (optional) error level, _OR_ in the case of 830 * PEAR_ERROR_CALLBACK, the callback function or object/method 831 * tuple. 832 * 833 * @param string $userinfo (optional) additional user/debug info 834 * 835 * @access public 836 * 837 */ 838 function __construct($message = 'unknown error', $code = null, 839 $mode = null, $options = null, $userinfo = null) 840 { 841 if ($mode === null) { 842 $mode = PEAR_ERROR_RETURN; 843 } 844 $this->message = $message; 845 $this->code = $code; 846 $this->mode = $mode; 847 $this->userinfo = $userinfo; 848 849 if (PEAR_ZE2) { 850 $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace'); 851 } else { 852 $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); 853 } 854 855 if (!$skiptrace) { 856 $this->backtrace = debug_backtrace(); 857 if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) { 858 unset($this->backtrace[0]['object']); 859 } 860 } 861 862 if ($mode & PEAR_ERROR_CALLBACK) { 863 $this->level = E_USER_NOTICE; 864 $this->callback = $options; 865 } else { 866 if ($options === null) { 867 $options = E_USER_NOTICE; 868 } 869 870 $this->level = $options; 871 $this->callback = null; 872 } 873 874 if ($this->mode & PEAR_ERROR_PRINT) { 875 if (is_null($options) || is_int($options)) { 876 $format = "%s"; 877 } else { 878 $format = $options; 879 } 880 881 printf($format, $this->getMessage()); 882 } 883 884 if ($this->mode & PEAR_ERROR_TRIGGER) { 885 trigger_error($this->getMessage(), $this->level); 886 } 887 888 if ($this->mode & PEAR_ERROR_DIE) { 889 $msg = $this->getMessage(); 890 if (is_null($options) || is_int($options)) { 891 $format = "%s"; 892 if (substr($msg, -1) != "\n") { 893 $msg .= "\n"; 894 } 895 } else { 896 $format = $options; 897 } 898 die(sprintf($format, $msg)); 899 } 900 901 if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) { 902 call_user_func($this->callback, $this); 903 } 904 905 if ($this->mode & PEAR_ERROR_EXCEPTION) { 906 trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); 907 eval('$e = new Exception($this->message, $this->code);throw($e);'); 908 } 909 } 910 911 /** 912 * Old syntax of class constructor for backward compatibility. 913 */ 914 public function PEAR_Error($message = 'unknown error', $code = null, 915 $mode = null, $options = null, $userinfo = null) { 916 self::__construct($message, $code, $mode, $options, $userinfo); 917 } 918 919 /** 920 * Get the error mode from an error object. 921 * 922 * @return int error mode 923 * @access public 924 */ 925 function getMode() 926 { 927 return $this->mode; 928 } 929 930 /** 931 * Get the callback function/method from an error object. 932 * 933 * @return mixed callback function or object/method array 934 * @access public 935 */ 936 function getCallback() 937 { 938 return $this->callback; 939 } 940 941 /** 942 * Get the error message from an error object. 943 * 944 * @return string full error message 945 * @access public 946 */ 947 function getMessage() 948 { 949 return ($this->error_message_prefix . $this->message); 950 } 951 952 /** 953 * Get error code from an error object 954 * 955 * @return int error code 956 * @access public 957 */ 958 function getCode() 959 { 960 return $this->code; 961 } 962 963 /** 964 * Get the name of this error/exception. 965 * 966 * @return string error/exception name (type) 967 * @access public 968 */ 969 function getType() 970 { 971 return get_class($this); 972 } 973 974 /** 975 * Get additional user-supplied information. 976 * 977 * @return string user-supplied information 978 * @access public 979 */ 980 function getUserInfo() 981 { 982 return $this->userinfo; 983 } 984 985 /** 986 * Get additional debug information supplied by the application. 987 * 988 * @return string debug information 989 * @access public 990 */ 991 function getDebugInfo() 992 { 993 return $this->getUserInfo(); 994 } 995 996 /** 997 * Get the call backtrace from where the error was generated. 998 * Supported with PHP 4.3.0 or newer. 999 * 1000 * @param int $frame (optional) what frame to fetch 1001 * @return array Backtrace, or NULL if not available. 1002 * @access public 1003 */ 1004 function getBacktrace($frame = null) 1005 { 1006 if (defined('PEAR_IGNORE_BACKTRACE')) { 1007 return null; 1008 } 1009 if ($frame === null) { 1010 return $this->backtrace; 1011 } 1012 return $this->backtrace[$frame]; 1013 } 1014 1015 function addUserInfo($info) 1016 { 1017 if (empty($this->userinfo)) { 1018 $this->userinfo = $info; 1019 } else { 1020 $this->userinfo .= " ** $info"; 1021 } 1022 } 1023 1024 function __toString() 1025 { 1026 return $this->getMessage(); 1027 } 1028 1029 /** 1030 * Make a string representation of this object. 1031 * 1032 * @return string a string with an object summary 1033 * @access public 1034 */ 1035 function toString() 1036 { 1037 $modes = array(); 1038 $levels = array(E_USER_NOTICE => 'notice', 1039 E_USER_WARNING => 'warning', 1040 E_USER_ERROR => 'error'); 1041 if ($this->mode & PEAR_ERROR_CALLBACK) { 1042 if (is_array($this->callback)) { 1043 $callback = (is_object($this->callback[0]) ? 1044 strtolower(get_class($this->callback[0])) : 1045 $this->callback[0]) . '::' . 1046 $this->callback[1]; 1047 } else { 1048 $callback = $this->callback; 1049 } 1050 return sprintf('[%s: message="%s" code=%d mode=callback '. 1051 'callback=%s prefix="%s" info="%s"]', 1052 strtolower(get_class($this)), $this->message, $this->code, 1053 $callback, $this->error_message_prefix, 1054 $this->userinfo); 1055 } 1056 if ($this->mode & PEAR_ERROR_PRINT) { 1057 $modes[] = 'print'; 1058 } 1059 if ($this->mode & PEAR_ERROR_TRIGGER) { 1060 $modes[] = 'trigger'; 1061 } 1062 if ($this->mode & PEAR_ERROR_DIE) { 1063 $modes[] = 'die'; 1064 } 1065 if ($this->mode & PEAR_ERROR_RETURN) { 1066 $modes[] = 'return'; 1067 } 1068 return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. 1069 'prefix="%s" info="%s"]', 1070 strtolower(get_class($this)), $this->message, $this->code, 1071 implode("|", $modes), $levels[$this->level], 1072 $this->error_message_prefix, 1073 $this->userinfo); 1074 } 1075 } 1076 1077 /* 1078 * Local Variables: 1079 * mode: php 1080 * tab-width: 4 1081 * c-basic-offset: 4 1082 * End: 1083 */
title
Description
Body
title
Description
Body
title
Description
Body
title
Body