Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

PEAR.php

Go to the documentation of this file.
00001 <?php 00002 // 00003 // +----------------------------------------------------------------------+ 00004 // | PHP Version 4 | 00005 // +----------------------------------------------------------------------+ 00006 // | Copyright (c) 1997-2003 The PHP Group | 00007 // +----------------------------------------------------------------------+ 00008 // | This source file is subject to version 2.0 of the PHP license, | 00009 // | that is bundled with this package in the file LICENSE, and is | 00010 // | available at through the world-wide-web at | 00011 // | http://www.php.net/license/2_02.txt. | 00012 // | If you did not receive a copy of the PHP license and are unable to | 00013 // | obtain it through the world-wide-web, please send a note to | 00014 // | license@php.net so we can mail you a copy immediately. | 00015 // +----------------------------------------------------------------------+ 00016 // | Authors: Sterling Hughes <sterling@php.net> | 00017 // | Stig Bakken <ssb@fast.no> | 00018 // | Tomas V.V.Cox <cox@idecnet.com> | 00019 // +----------------------------------------------------------------------+ 00020 // 00021 // $Id: PEAR.php,v 1.1 2004/03/23 22:21:59 jeluf Exp $ 00022 // 00023 00024 define('PEAR_ERROR_RETURN', 1); 00025 define('PEAR_ERROR_PRINT', 2); 00026 define('PEAR_ERROR_TRIGGER', 4); 00027 define('PEAR_ERROR_DIE', 8); 00028 define('PEAR_ERROR_CALLBACK', 16); 00029 define('PEAR_ZE2', (function_exists('version_compare') && 00030 version_compare(zend_version(), "2-dev", "ge"))); 00031 00032 if (substr(PHP_OS, 0, 3) == 'WIN') { 00033 define('OS_WINDOWS', true); 00034 define('OS_UNIX', false); 00035 define('PEAR_OS', 'Windows'); 00036 } else { 00037 define('OS_WINDOWS', false); 00038 define('OS_UNIX', true); 00039 define('PEAR_OS', 'Unix'); // blatant assumption 00040 } 00041 00042 $GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; 00043 $GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; 00044 $GLOBALS['_PEAR_destructor_object_list'] = array(); 00045 $GLOBALS['_PEAR_shutdown_funcs'] = array(); 00046 $GLOBALS['_PEAR_error_handler_stack'] = array(); 00047 00048 ini_set('track_errors', true); 00049 00071 class PEAR 00072 { 00073 // {{{ properties 00074 00081 var $_debug = false; 00082 00089 var $_default_error_mode = null; 00090 00098 var $_default_error_options = null; 00099 00107 var $_default_error_handler = ''; 00108 00115 var $_error_class = 'PEAR_Error'; 00116 00123 var $_expected_errors = array(); 00124 00125 // }}} 00126 00127 // {{{ constructor 00128 00139 function PEAR($error_class = null) 00140 { 00141 $classname = get_class($this); 00142 if ($this->_debug) { 00143 print "PEAR constructor called, class=$classname\n"; 00144 } 00145 if ($error_class !== null) { 00146 $this->_error_class = $error_class; 00147 } 00148 while ($classname) { 00149 $destructor = "_$classname"; 00150 if (method_exists($this, $destructor)) { 00151 global $_PEAR_destructor_object_list; 00152 $_PEAR_destructor_object_list[] = &$this; 00153 break; 00154 } else { 00155 $classname = get_parent_class($classname); 00156 } 00157 } 00158 } 00159 00160 // }}} 00161 // {{{ destructor 00162 00174 function _PEAR() { 00175 if ($this->_debug) { 00176 printf("PEAR destructor called, class=%s\n", get_class($this)); 00177 } 00178 } 00179 00180 // }}} 00181 // {{{ getStaticProperty() 00182 00195 function &getStaticProperty($class, $var) 00196 { 00197 static $properties; 00198 return $properties[$class][$var]; 00199 } 00200 00201 // }}} 00202 // {{{ registerShutdownFunc() 00203 00213 function registerShutdownFunc($func, $args = array()) 00214 { 00215 $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); 00216 } 00217 00218 // }}} 00219 // {{{ isError() 00220 00228 function isError($data) { 00229 return (bool)(is_object($data) && 00230 (get_class($data) == 'pear_error' || 00231 is_subclass_of($data, 'pear_error'))); 00232 } 00233 00234 // }}} 00235 // {{{ setErrorHandling() 00236 00275 function setErrorHandling($mode = null, $options = null) 00276 { 00277 if (isset($this)) { 00278 $setmode = &$this->_default_error_mode; 00279 $setoptions = &$this->_default_error_options; 00280 } else { 00281 $setmode = &$GLOBALS['_PEAR_default_error_mode']; 00282 $setoptions = &$GLOBALS['_PEAR_default_error_options']; 00283 } 00284 00285 switch ($mode) { 00286 case PEAR_ERROR_RETURN: 00287 case PEAR_ERROR_PRINT: 00288 case PEAR_ERROR_TRIGGER: 00289 case PEAR_ERROR_DIE: 00290 case null: 00291 $setmode = $mode; 00292 $setoptions = $options; 00293 break; 00294 00295 case PEAR_ERROR_CALLBACK: 00296 $setmode = $mode; 00297 if ((is_string($options) && function_exists($options)) || 00298 (is_array($options) && method_exists(@$options[0], @$options[1]))) 00299 { 00300 $setoptions = $options; 00301 } else { 00302 trigger_error("invalid error callback", E_USER_WARNING); 00303 } 00304 break; 00305 00306 default: 00307 trigger_error("invalid error mode", E_USER_WARNING); 00308 break; 00309 } 00310 } 00311 00312 // }}} 00313 // {{{ expectError() 00314 00330 function expectError($code = '*') 00331 { 00332 if (is_array($code)) { 00333 array_push($this->_expected_errors, $code); 00334 } else { 00335 array_push($this->_expected_errors, array($code)); 00336 } 00337 return sizeof($this->_expected_errors); 00338 } 00339 00340 // }}} 00341 // {{{ popExpect() 00342 00349 function popExpect() 00350 { 00351 return array_pop($this->_expected_errors); 00352 } 00353 00354 // }}} 00355 // {{{ _checkDelExpect() 00356 00365 function _checkDelExpect($error_code) 00366 { 00367 $deleted = false; 00368 00369 foreach ($this->_expected_errors AS $key => $error_array) { 00370 if (in_array($error_code, $error_array)) { 00371 unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); 00372 $deleted = true; 00373 } 00374 00375 // clean up empty arrays 00376 if (0 == count($this->_expected_errors[$key])) { 00377 unset($this->_expected_errors[$key]); 00378 } 00379 } 00380 return $deleted; 00381 } 00382 00383 // }}} 00384 // {{{ delExpect() 00385 00395 function delExpect($error_code) 00396 { 00397 $deleted = false; 00398 00399 if ((is_array($error_code) && (0 != count($error_code)))) { 00400 // $error_code is a non-empty array here; 00401 // we walk through it trying to unset all 00402 // values 00403 foreach($error_code AS $key => $error) { 00404 if ($this->_checkDelExpect($error)) { 00405 $deleted = true; 00406 } else { 00407 $deleted = false; 00408 } 00409 } 00410 return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME 00411 } elseif (!empty($error_code)) { 00412 // $error_code comes alone, trying to unset it 00413 if ($this->_checkDelExpect($error_code)) { 00414 return true; 00415 } else { 00416 return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME 00417 } 00418 } else { 00419 // $error_code is empty 00420 return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME 00421 } 00422 } 00423 00424 // }}} 00425 // {{{ raiseError() 00426 00464 function &raiseError($message = null, 00465 $code = null, 00466 $mode = null, 00467 $options = null, 00468 $userinfo = null, 00469 $error_class = null, 00470 $skipmsg = false) 00471 { 00472 // The error is yet a PEAR error object 00473 if (is_object($message)) { 00474 $code = $message->getCode(); 00475 $userinfo = $message->getUserInfo(); 00476 $error_class = $message->getType(); 00477 $message = $message->getMessage(); 00478 } 00479 00480 if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) { 00481 if ($exp[0] == "*" || 00482 (is_int(reset($exp)) && in_array($code, $exp)) || 00483 (is_string(reset($exp)) && in_array($message, $exp))) { 00484 $mode = PEAR_ERROR_RETURN; 00485 } 00486 } 00487 // No mode given, try global ones 00488 if ($mode === null) { 00489 // Class error handler 00490 if (isset($this) && isset($this->_default_error_mode)) { 00491 $mode = $this->_default_error_mode; 00492 $options = $this->_default_error_options; 00493 // Global error handler 00494 } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { 00495 $mode = $GLOBALS['_PEAR_default_error_mode']; 00496 $options = $GLOBALS['_PEAR_default_error_options']; 00497 } 00498 } 00499 00500 if ($error_class !== null) { 00501 $ec = $error_class; 00502 } elseif (isset($this) && isset($this->_error_class)) { 00503 $ec = $this->_error_class; 00504 } else { 00505 $ec = 'PEAR_Error'; 00506 } 00507 if ($skipmsg) { 00508 return new $ec($code, $mode, $options, $userinfo); 00509 } else { 00510 return new $ec($message, $code, $mode, $options, $userinfo); 00511 } 00512 } 00513 00514 // }}} 00515 // {{{ throwError() 00516 00524 function &throwError($message = null, 00525 $code = null, 00526 $userinfo = null) 00527 { 00528 if (isset($this)) { 00529 return $this->raiseError($message, $code, null, null, $userinfo); 00530 } else { 00531 return PEAR::raiseError($message, $code, null, null, $userinfo); 00532 } 00533 } 00534 00535 // }}} 00536 // {{{ pushErrorHandling() 00537 00550 function pushErrorHandling($mode, $options = null) 00551 { 00552 $stack = &$GLOBALS['_PEAR_error_handler_stack']; 00553 if (isset($this)) { 00554 $def_mode = &$this->_default_error_mode; 00555 $def_options = &$this->_default_error_options; 00556 } else { 00557 $def_mode = &$GLOBALS['_PEAR_default_error_mode']; 00558 $def_options = &$GLOBALS['_PEAR_default_error_options']; 00559 } 00560 $stack[] = array($def_mode, $def_options); 00561 00562 if (isset($this)) { 00563 $this->setErrorHandling($mode, $options); 00564 } else { 00565 PEAR::setErrorHandling($mode, $options); 00566 } 00567 $stack[] = array($mode, $options); 00568 return true; 00569 } 00570 00571 // }}} 00572 // {{{ popErrorHandling() 00573 00581 function popErrorHandling() 00582 { 00583 $stack = &$GLOBALS['_PEAR_error_handler_stack']; 00584 array_pop($stack); 00585 list($mode, $options) = $stack[sizeof($stack) - 1]; 00586 array_pop($stack); 00587 if (isset($this)) { 00588 $this->setErrorHandling($mode, $options); 00589 } else { 00590 PEAR::setErrorHandling($mode, $options); 00591 } 00592 return true; 00593 } 00594 00595 // }}} 00596 // {{{ loadExtension() 00597 00605 function loadExtension($ext) 00606 { 00607 if (!extension_loaded($ext)) { 00608 if (OS_WINDOWS) { 00609 $suffix = '.dll'; 00610 } elseif (PHP_OS == 'HP-UX') { 00611 $suffix = '.sl'; 00612 } elseif (PHP_OS == 'AIX') { 00613 $suffix = '.a'; 00614 } elseif (PHP_OS == 'OSX') { 00615 $suffix = '.bundle'; 00616 } else { 00617 $suffix = '.so'; 00618 } 00619 return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); 00620 } 00621 return true; 00622 } 00623 00624 // }}} 00625 } 00626 00627 // {{{ _PEAR_call_destructors() 00628 00629 function _PEAR_call_destructors() 00630 { 00631 global $_PEAR_destructor_object_list; 00632 if (is_array($_PEAR_destructor_object_list) && 00633 sizeof($_PEAR_destructor_object_list)) 00634 { 00635 reset($_PEAR_destructor_object_list); 00636 while (list($k, $objref) = each($_PEAR_destructor_object_list)) { 00637 $classname = get_class($objref); 00638 while ($classname) { 00639 $destructor = "_$classname"; 00640 if (method_exists($objref, $destructor)) { 00641 $objref->$destructor(); 00642 break; 00643 } else { 00644 $classname = get_parent_class($classname); 00645 } 00646 } 00647 } 00648 // Empty the object list to ensure that destructors are 00649 // not called more than once. 00650 $_PEAR_destructor_object_list = array(); 00651 } 00652 00653 // Now call the shutdown functions 00654 if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { 00655 foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { 00656 call_user_func_array($value[0], $value[1]); 00657 } 00658 } 00659 } 00660 00661 // }}} 00662 00663 class PEAR_Error 00664 { 00665 // {{{ properties 00666 00667 var $error_message_prefix = ''; 00668 var $mode = PEAR_ERROR_RETURN; 00669 var $level = E_USER_NOTICE; 00670 var $code = -1; 00671 var $message = ''; 00672 var $userinfo = ''; 00673 var $backtrace = null; 00674 00675 // }}} 00676 // {{{ constructor 00677 00698 function PEAR_Error($message = 'unknown error', $code = null, 00699 $mode = null, $options = null, $userinfo = null) 00700 { 00701 if ($mode === null) { 00702 $mode = PEAR_ERROR_RETURN; 00703 } 00704 $this->message = $message; 00705 $this->code = $code; 00706 $this->mode = $mode; 00707 $this->userinfo = $userinfo; 00708 if (function_exists("debug_backtrace")) { 00709 $this->backtrace = debug_backtrace(); 00710 } 00711 if ($mode & PEAR_ERROR_CALLBACK) { 00712 $this->level = E_USER_NOTICE; 00713 $this->callback = $options; 00714 } else { 00715 if ($options === null) { 00716 $options = E_USER_NOTICE; 00717 } 00718 $this->level = $options; 00719 $this->callback = null; 00720 } 00721 if ($this->mode & PEAR_ERROR_PRINT) { 00722 if (is_null($options) || is_int($options)) { 00723 $format = "%s"; 00724 } else { 00725 $format = $options; 00726 } 00727 printf($format, $this->getMessage()); 00728 } 00729 if ($this->mode & PEAR_ERROR_TRIGGER) { 00730 trigger_error($this->getMessage(), $this->level); 00731 } 00732 if ($this->mode & PEAR_ERROR_DIE) { 00733 $msg = $this->getMessage(); 00734 if (is_null($options) || is_int($options)) { 00735 $format = "%s"; 00736 if (substr($msg, -1) != "\n") { 00737 $msg .= "\n"; 00738 } 00739 } else { 00740 $format = $options; 00741 } 00742 die(sprintf($format, $msg)); 00743 } 00744 if ($this->mode & PEAR_ERROR_CALLBACK) { 00745 if (is_string($this->callback) && strlen($this->callback)) { 00746 call_user_func($this->callback, $this); 00747 } elseif (is_array($this->callback) && 00748 sizeof($this->callback) == 2 && 00749 is_object($this->callback[0]) && 00750 is_string($this->callback[1]) && 00751 strlen($this->callback[1])) { 00752 @call_user_func($this->callback, $this); 00753 } 00754 } 00755 } 00756 00757 // }}} 00758 // {{{ getMode() 00759 00766 function getMode() { 00767 return $this->mode; 00768 } 00769 00770 // }}} 00771 // {{{ getCallback() 00772 00779 function getCallback() { 00780 return $this->callback; 00781 } 00782 00783 // }}} 00784 // {{{ getMessage() 00785 00786 00793 function getMessage() 00794 { 00795 return ($this->error_message_prefix . $this->message); 00796 } 00797 00798 00799 // }}} 00800 // {{{ getCode() 00801 00808 function getCode() 00809 { 00810 return $this->code; 00811 } 00812 00813 // }}} 00814 // {{{ getType() 00815 00822 function getType() 00823 { 00824 return get_class($this); 00825 } 00826 00827 // }}} 00828 // {{{ getUserInfo() 00829 00836 function getUserInfo() 00837 { 00838 return $this->userinfo; 00839 } 00840 00841 // }}} 00842 // {{{ getDebugInfo() 00843 00850 function getDebugInfo() 00851 { 00852 return $this->getUserInfo(); 00853 } 00854 00855 // }}} 00856 // {{{ getBacktrace() 00857 00866 function getBacktrace($frame = null) 00867 { 00868 if ($frame === null) { 00869 return $this->backtrace; 00870 } 00871 return $this->backtrace[$frame]; 00872 } 00873 00874 // }}} 00875 // {{{ addUserInfo() 00876 00877 function addUserInfo($info) 00878 { 00879 if (empty($this->userinfo)) { 00880 $this->userinfo = $info; 00881 } else { 00882 $this->userinfo .= " ** $info"; 00883 } 00884 } 00885 00886 // }}} 00887 // {{{ toString() 00888 00895 function toString() { 00896 $modes = array(); 00897 $levels = array(E_USER_NOTICE => 'notice', 00898 E_USER_WARNING => 'warning', 00899 E_USER_ERROR => 'error'); 00900 if ($this->mode & PEAR_ERROR_CALLBACK) { 00901 if (is_array($this->callback)) { 00902 $callback = get_class($this->callback[0]) . '::' . 00903 $this->callback[1]; 00904 } else { 00905 $callback = $this->callback; 00906 } 00907 return sprintf('[%s: message="%s" code=%d mode=callback '. 00908 'callback=%s prefix="%s" info="%s"]', 00909 get_class($this), $this->message, $this->code, 00910 $callback, $this->error_message_prefix, 00911 $this->userinfo); 00912 } 00913 if ($this->mode & PEAR_ERROR_PRINT) { 00914 $modes[] = 'print'; 00915 } 00916 if ($this->mode & PEAR_ERROR_TRIGGER) { 00917 $modes[] = 'trigger'; 00918 } 00919 if ($this->mode & PEAR_ERROR_DIE) { 00920 $modes[] = 'die'; 00921 } 00922 if ($this->mode & PEAR_ERROR_RETURN) { 00923 $modes[] = 'return'; 00924 } 00925 return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. 00926 'prefix="%s" info="%s"]', 00927 get_class($this), $this->message, $this->code, 00928 implode("|", $modes), $levels[$this->level], 00929 $this->error_message_prefix, 00930 $this->userinfo); 00931 } 00932 00933 // }}} 00934 } 00935 00936 register_shutdown_function("_PEAR_call_destructors"); 00937 00938 /* 00939 * Local Variables: 00940 * mode: php 00941 * tab-width: 4 00942 * c-basic-offset: 4 00943 * End: 00944 */ 00945 ?>

Generated on Tue Jun 29 23:40:06 2004 for Mediawiki by doxygen 1.3.7