Xataface 2.0
Xataface Application Framework
PEAR.php
Go to the documentation of this file.
00001 <?php
00031 define('PEAR_ERROR_RETURN',     1);
00032 define('PEAR_ERROR_PRINT',      2);
00033 define('PEAR_ERROR_TRIGGER',    4);
00034 define('PEAR_ERROR_DIE',        8);
00035 define('PEAR_ERROR_CALLBACK',  16);
00040 define('PEAR_ERROR_EXCEPTION', 32);
00042 define('PEAR_ZE2', (function_exists('version_compare') &&
00043                     version_compare(zend_version(), "2-dev", "ge")));
00044 
00045 if (substr(PHP_OS, 0, 3) == 'WIN') {
00046     define('OS_WINDOWS', true);
00047     define('OS_UNIX',    false);
00048     define('PEAR_OS',    'Windows');
00049 } else {
00050     define('OS_WINDOWS', false);
00051     define('OS_UNIX',    true);
00052     define('PEAR_OS',    'Unix'); // blatant assumption
00053 }
00054 
00055 // instant backwards compatibility
00056 if (!defined('PATH_SEPARATOR')) {
00057     if (OS_WINDOWS) {
00058         define('PATH_SEPARATOR', ';');
00059     } else {
00060         define('PATH_SEPARATOR', ':');
00061     }
00062 }
00063 
00064 $GLOBALS['_PEAR_default_error_mode']     = PEAR_ERROR_RETURN;
00065 $GLOBALS['_PEAR_default_error_options']  = E_USER_NOTICE;
00066 $GLOBALS['_PEAR_destructor_object_list'] = array();
00067 $GLOBALS['_PEAR_shutdown_funcs']         = array();
00068 $GLOBALS['_PEAR_error_handler_stack']    = array();
00069 
00070 @ini_set('track_errors', true);
00071 
00102 class PEAR
00103 {
00104     // {{{ properties
00105 
00112     var $_debug = false;
00113 
00120     var $_default_error_mode = null;
00121 
00129     var $_default_error_options = null;
00130 
00138     var $_default_error_handler = '';
00139 
00146     var $_error_class = 'PEAR_Error';
00147 
00154     var $_expected_errors = array();
00155 
00156     // }}}
00157 
00158     // {{{ constructor
00159 
00170     function PEAR($error_class = null)
00171     {
00172         $classname = strtolower(get_class($this));
00173         if ($this->_debug) {
00174             print "PEAR constructor called, class=$classname\n";
00175         }
00176         if ($error_class !== null) {
00177             $this->_error_class = $error_class;
00178         }
00179         while ($classname && strcasecmp($classname, "pear")) {
00180             $destructor = "_$classname";
00181             if (method_exists($this, $destructor)) {
00182                 global $_PEAR_destructor_object_list;
00183                 $_PEAR_destructor_object_list[] = &$this;
00184                 if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
00185                     register_shutdown_function("_PEAR_call_destructors");
00186                     $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
00187                 }
00188                 break;
00189             } else {
00190                 $classname = get_parent_class($classname);
00191             }
00192         }
00193     }
00194 
00195     // }}}
00196     // {{{ destructor
00197 
00209     function _PEAR() {
00210         if ($this->_debug) {
00211             printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
00212         }
00213     }
00214 
00215     // }}}
00216     // {{{ getStaticProperty()
00217 
00230     public static function &getStaticProperty($class, $var)
00231     {
00232         static $properties;
00233         if (!isset($properties[$class])) {
00234             $properties[$class] = array();
00235         }
00236         if (!array_key_exists($var, $properties[$class])) {
00237             $properties[$class][$var] = null;
00238         }
00239         return $properties[$class][$var];
00240     }
00241 
00242     // }}}
00243     // {{{ registerShutdownFunc()
00244 
00254     function registerShutdownFunc($func, $args = array())
00255     {
00256         // if we are called statically, there is a potential
00257         // that no shutdown func is registered.  Bug #6445
00258         if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
00259             register_shutdown_function("_PEAR_call_destructors");
00260             $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
00261         }
00262         $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
00263     }
00264 
00265     // }}}
00266     // {{{ isError()
00267 
00279     public static function isError($data, $code = null)
00280     {
00281         if (is_a($data, 'PEAR_Error')) {
00282             if (is_null($code)) {
00283                 return true;
00284             } elseif (is_string($code)) {
00285                 return $data->getMessage() == $code;
00286             } else {
00287                 return $data->getCode() == $code;
00288             }
00289         }
00290         return false;
00291     }
00292 
00293     // }}}
00294     // {{{ setErrorHandling()
00295 
00335     function setErrorHandling($mode = null, $options = null)
00336     {
00337         if (isset($this) && is_a($this, 'PEAR')) {
00338             $setmode     = &$this->_default_error_mode;
00339             $setoptions  = &$this->_default_error_options;
00340         } else {
00341             $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
00342             $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
00343         }
00344 
00345         switch ($mode) {
00346             case PEAR_ERROR_EXCEPTION:
00347             case PEAR_ERROR_RETURN:
00348             case PEAR_ERROR_PRINT:
00349             case PEAR_ERROR_TRIGGER:
00350             case PEAR_ERROR_DIE:
00351             case null:
00352                 $setmode = $mode;
00353                 $setoptions = $options;
00354                 break;
00355 
00356             case PEAR_ERROR_CALLBACK:
00357                 $setmode = $mode;
00358                 // class/object method callback
00359                 if (is_callable($options)) {
00360                     $setoptions = $options;
00361                 } else {
00362                     trigger_error("invalid error callback", E_USER_WARNING);
00363                 }
00364                 break;
00365 
00366             default:
00367                 trigger_error("invalid error mode", E_USER_WARNING);
00368                 break;
00369         }
00370     }
00371 
00372     // }}}
00373     // {{{ expectError()
00374 
00390     function expectError($code = '*')
00391     {
00392         if (is_array($code)) {
00393             array_push($this->_expected_errors, $code);
00394         } else {
00395             array_push($this->_expected_errors, array($code));
00396         }
00397         return sizeof($this->_expected_errors);
00398     }
00399 
00400     // }}}
00401     // {{{ popExpect()
00402 
00409     function popExpect()
00410     {
00411         return array_pop($this->_expected_errors);
00412     }
00413 
00414     // }}}
00415     // {{{ _checkDelExpect()
00416 
00425     function _checkDelExpect($error_code)
00426     {
00427         $deleted = false;
00428 
00429         foreach ($this->_expected_errors AS $key => $error_array) {
00430             if (in_array($error_code, $error_array)) {
00431                 unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
00432                 $deleted = true;
00433             }
00434 
00435             // clean up empty arrays
00436             if (0 == count($this->_expected_errors[$key])) {
00437                 unset($this->_expected_errors[$key]);
00438             }
00439         }
00440         return $deleted;
00441     }
00442 
00443     // }}}
00444     // {{{ delExpect()
00445 
00455     function delExpect($error_code)
00456     {
00457         $deleted = false;
00458 
00459         if ((is_array($error_code) && (0 != count($error_code)))) {
00460             // $error_code is a non-empty array here;
00461             // we walk through it trying to unset all
00462             // values
00463             foreach($error_code as $key => $error) {
00464                 if ($this->_checkDelExpect($error)) {
00465                     $deleted =  true;
00466                 } else {
00467                     $deleted = false;
00468                 }
00469             }
00470             return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
00471         } elseif (!empty($error_code)) {
00472             // $error_code comes alone, trying to unset it
00473             if ($this->_checkDelExpect($error_code)) {
00474                 return true;
00475             } else {
00476                 return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
00477             }
00478         } else {
00479             // $error_code is empty
00480             return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
00481         }
00482     }
00483 
00484     // }}}
00485     // {{{ raiseError()
00486 
00524     public static function &raiseError($message = null,
00525                          $code = null,
00526                          $mode = null,
00527                          $options = null,
00528                          $userinfo = null,
00529                          $error_class = null,
00530                          $skipmsg = false)
00531     {
00532         // The error is yet a PEAR error object
00533         if (is_object($message)) {
00534             $code        = $message->getCode();
00535             $userinfo    = $message->getUserInfo();
00536             $error_class = $message->getType();
00537             $message->error_message_prefix = '';
00538             $message     = $message->getMessage();
00539         }
00540 
00541         if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
00542             if ($exp[0] == "*" ||
00543                 (is_int(reset($exp)) && in_array($code, $exp)) ||
00544                 (is_string(reset($exp)) && in_array($message, $exp))) {
00545                 $mode = PEAR_ERROR_RETURN;
00546             }
00547         }
00548         // No mode given, try global ones
00549         if ($mode === null) {
00550             // Class error handler
00551             if (isset($this) && isset($this->_default_error_mode)) {
00552                 $mode    = $this->_default_error_mode;
00553                 $options = $this->_default_error_options;
00554             // Global error handler
00555             } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
00556                 $mode    = $GLOBALS['_PEAR_default_error_mode'];
00557                 $options = $GLOBALS['_PEAR_default_error_options'];
00558             }
00559         }
00560 
00561         if ($error_class !== null) {
00562             $ec = $error_class;
00563         } elseif (isset($this) && isset($this->_error_class)) {
00564             $ec = $this->_error_class;
00565         } else {
00566             $ec = 'PEAR_Error';
00567         }
00568         if (intval(PHP_VERSION) < 5) {
00569             // little non-eval hack to fix bug #12147
00570             include 'PEAR/FixPHP5PEARWarnings.php';
00571             return $a;
00572         }
00573         if ($skipmsg) {
00574             $a = new $ec($code, $mode, $options, $userinfo);
00575         } else {
00576             $a = new $ec($message, $code, $mode, $options, $userinfo);
00577         }
00578         return $a;
00579     }
00580 
00581     // }}}
00582     // {{{ throwError()
00583 
00591     function &throwError($message = null,
00592                          $code = null,
00593                          $userinfo = null)
00594     {
00595         if (isset($this) && is_a($this, 'PEAR')) {
00596             $a = &$this->raiseError($message, $code, null, null, $userinfo);
00597             return $a;
00598         } else {
00599             $a = &PEAR::raiseError($message, $code, null, null, $userinfo);
00600             return $a;
00601         }
00602     }
00603 
00604     // }}}
00605     function staticPushErrorHandling($mode, $options = null)
00606     {
00607         $stack = &$GLOBALS['_PEAR_error_handler_stack'];
00608         $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
00609         $def_options = &$GLOBALS['_PEAR_default_error_options'];
00610         $stack[] = array($def_mode, $def_options);
00611         switch ($mode) {
00612             case PEAR_ERROR_EXCEPTION:
00613             case PEAR_ERROR_RETURN:
00614             case PEAR_ERROR_PRINT:
00615             case PEAR_ERROR_TRIGGER:
00616             case PEAR_ERROR_DIE:
00617             case null:
00618                 $def_mode = $mode;
00619                 $def_options = $options;
00620                 break;
00621 
00622             case PEAR_ERROR_CALLBACK:
00623                 $def_mode = $mode;
00624                 // class/object method callback
00625                 if (is_callable($options)) {
00626                     $def_options = $options;
00627                 } else {
00628                     trigger_error("invalid error callback", E_USER_WARNING);
00629                 }
00630                 break;
00631 
00632             default:
00633                 trigger_error("invalid error mode", E_USER_WARNING);
00634                 break;
00635         }
00636         $stack[] = array($mode, $options);
00637         return true;
00638     }
00639 
00640     function staticPopErrorHandling()
00641     {
00642         $stack = &$GLOBALS['_PEAR_error_handler_stack'];
00643         $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
00644         $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
00645         array_pop($stack);
00646         list($mode, $options) = $stack[sizeof($stack) - 1];
00647         array_pop($stack);
00648         switch ($mode) {
00649             case PEAR_ERROR_EXCEPTION:
00650             case PEAR_ERROR_RETURN:
00651             case PEAR_ERROR_PRINT:
00652             case PEAR_ERROR_TRIGGER:
00653             case PEAR_ERROR_DIE:
00654             case null:
00655                 $setmode = $mode;
00656                 $setoptions = $options;
00657                 break;
00658 
00659             case PEAR_ERROR_CALLBACK:
00660                 $setmode = $mode;
00661                 // class/object method callback
00662                 if (is_callable($options)) {
00663                     $setoptions = $options;
00664                 } else {
00665                     trigger_error("invalid error callback", E_USER_WARNING);
00666                 }
00667                 break;
00668 
00669             default:
00670                 trigger_error("invalid error mode", E_USER_WARNING);
00671                 break;
00672         }
00673         return true;
00674     }
00675 
00676     // {{{ pushErrorHandling()
00677 
00690     function pushErrorHandling($mode, $options = null)
00691     {
00692         $stack = &$GLOBALS['_PEAR_error_handler_stack'];
00693         if (isset($this) && is_a($this, 'PEAR')) {
00694             $def_mode    = &$this->_default_error_mode;
00695             $def_options = &$this->_default_error_options;
00696         } else {
00697             $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
00698             $def_options = &$GLOBALS['_PEAR_default_error_options'];
00699         }
00700         $stack[] = array($def_mode, $def_options);
00701 
00702         if (isset($this) && is_a($this, 'PEAR')) {
00703             $this->setErrorHandling($mode, $options);
00704         } else {
00705             PEAR::setErrorHandling($mode, $options);
00706         }
00707         $stack[] = array($mode, $options);
00708         return true;
00709     }
00710 
00711     // }}}
00712     // {{{ popErrorHandling()
00713 
00721     function popErrorHandling()
00722     {
00723         $stack = &$GLOBALS['_PEAR_error_handler_stack'];
00724         array_pop($stack);
00725         list($mode, $options) = $stack[sizeof($stack) - 1];
00726         array_pop($stack);
00727         if (isset($this) && is_a($this, 'PEAR')) {
00728             $this->setErrorHandling($mode, $options);
00729         } else {
00730             PEAR::setErrorHandling($mode, $options);
00731         }
00732         return true;
00733     }
00734 
00735     // }}}
00736     // {{{ loadExtension()
00737 
00745     function loadExtension($ext)
00746     {
00747         if (!extension_loaded($ext)) {
00748             // if either returns true dl() will produce a FATAL error, stop that
00749             if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
00750                 return false;
00751             }
00752             if (OS_WINDOWS) {
00753                 $suffix = '.dll';
00754             } elseif (PHP_OS == 'HP-UX') {
00755                 $suffix = '.sl';
00756             } elseif (PHP_OS == 'AIX') {
00757                 $suffix = '.a';
00758             } elseif (PHP_OS == 'OSX') {
00759                 $suffix = '.bundle';
00760             } else {
00761                 $suffix = '.so';
00762             }
00763             return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
00764         }
00765         return true;
00766     }
00767 
00768     // }}}
00769 }
00770 
00771 // {{{ _PEAR_call_destructors()
00772 
00773 function _PEAR_call_destructors()
00774 {
00775     global $_PEAR_destructor_object_list;
00776     if (is_array($_PEAR_destructor_object_list) &&
00777         sizeof($_PEAR_destructor_object_list))
00778     {
00779         reset($_PEAR_destructor_object_list);
00780         if (PEAR::getStaticProperty('PEAR', 'destructlifo')) {
00781             $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
00782         }
00783         while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
00784             $classname = get_class($objref);
00785             while ($classname) {
00786                 $destructor = "_$classname";
00787                 if (method_exists($objref, $destructor)) {
00788                     $objref->$destructor();
00789                     break;
00790                 } else {
00791                     $classname = get_parent_class($classname);
00792                 }
00793             }
00794         }
00795         // Empty the object list to ensure that destructors are
00796         // not called more than once.
00797         $_PEAR_destructor_object_list = array();
00798     }
00799 
00800     // Now call the shutdown functions
00801     if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
00802         foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
00803             call_user_func_array($value[0], $value[1]);
00804         }
00805     }
00806 }
00807 
00808 // }}}
00826 class PEAR_Error
00827 {
00828     // {{{ properties
00829 
00830     var $error_message_prefix = '';
00831     var $mode                 = PEAR_ERROR_RETURN;
00832     var $level                = E_USER_NOTICE;
00833     var $code                 = -1;
00834     var $message              = '';
00835     var $userinfo             = '';
00836     var $backtrace            = null;
00837 
00838     // }}}
00839     // {{{ constructor
00840 
00861     function PEAR_Error($message = 'unknown error', $code = null,
00862                         $mode = null, $options = null, $userinfo = null)
00863     {
00864         if ($mode === null) {
00865             $mode = PEAR_ERROR_RETURN;
00866         }
00867         $this->message   = $message;
00868         $this->code      = $code;
00869         $this->mode      = $mode;
00870         $this->userinfo  = $userinfo;
00871         if (!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
00872             $this->backtrace = debug_backtrace();
00873             if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
00874                 unset($this->backtrace[0]['object']);
00875             }
00876         }
00877         if ($mode & PEAR_ERROR_CALLBACK) {
00878             $this->level = E_USER_NOTICE;
00879             $this->callback = $options;
00880         } else {
00881             if ($options === null) {
00882                 $options = E_USER_NOTICE;
00883             }
00884             $this->level = $options;
00885             $this->callback = null;
00886         }
00887         if ($this->mode & PEAR_ERROR_PRINT) {
00888             if (is_null($options) || is_int($options)) {
00889                 $format = "%s";
00890             } else {
00891                 $format = $options;
00892             }
00893             printf($format, $this->getMessage());
00894         }
00895         if ($this->mode & PEAR_ERROR_TRIGGER) {
00896             trigger_error($this->getMessage(), $this->level);
00897         }
00898         if ($this->mode & PEAR_ERROR_DIE) {
00899             $msg = $this->getMessage();
00900             if (is_null($options) || is_int($options)) {
00901                 $format = "%s";
00902                 if (substr($msg, -1) != "\n") {
00903                     $msg .= "\n";
00904                 }
00905             } else {
00906                 $format = $options;
00907             }
00908             die(sprintf($format, $msg));
00909         }
00910         if ($this->mode & PEAR_ERROR_CALLBACK) {
00911             if (is_callable($this->callback)) {
00912                 call_user_func($this->callback, $this);
00913             }
00914         }
00915         if ($this->mode & PEAR_ERROR_EXCEPTION) {
00916             trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
00917             eval('$e = new Exception($this->message, $this->code);throw($e);');
00918         }
00919     }
00920 
00921     // }}}
00922     // {{{ getMode()
00923 
00930     function getMode() {
00931         return $this->mode;
00932     }
00933 
00934     // }}}
00935     // {{{ getCallback()
00936 
00943     function getCallback() {
00944         return $this->callback;
00945     }
00946 
00947     // }}}
00948     // {{{ getMessage()
00949 
00950 
00957     function getMessage()
00958     {
00959         return ($this->error_message_prefix . $this->message);
00960     }
00961 
00962 
00963     // }}}
00964     // {{{ getCode()
00965 
00972      function getCode()
00973      {
00974         return $this->code;
00975      }
00976 
00977     // }}}
00978     // {{{ getType()
00979 
00986     function getType()
00987     {
00988         return get_class($this);
00989     }
00990 
00991     // }}}
00992     // {{{ getUserInfo()
00993 
01000     function getUserInfo()
01001     {
01002         return $this->userinfo;
01003     }
01004 
01005     // }}}
01006     // {{{ getDebugInfo()
01007 
01014     function getDebugInfo()
01015     {
01016         return $this->getUserInfo();
01017     }
01018 
01019     // }}}
01020     // {{{ getBacktrace()
01021 
01030     function getBacktrace($frame = null)
01031     {
01032         if (defined('PEAR_IGNORE_BACKTRACE')) {
01033             return null;
01034         }
01035         if ($frame === null) {
01036             return $this->backtrace;
01037         }
01038         return $this->backtrace[$frame];
01039     }
01040 
01041     // }}}
01042     // {{{ addUserInfo()
01043 
01044     function addUserInfo($info)
01045     {
01046         if (empty($this->userinfo)) {
01047             $this->userinfo = $info;
01048         } else {
01049             $this->userinfo .= " ** $info";
01050         }
01051     }
01052 
01053     // }}}
01054     // {{{ toString()
01055     function __toString()
01056     {
01057         return $this->getMessage();
01058     }
01059     // }}}
01060     // {{{ toString()
01061 
01068     function toString() {
01069         $modes = array();
01070         $levels = array(E_USER_NOTICE  => 'notice',
01071                         E_USER_WARNING => 'warning',
01072                         E_USER_ERROR   => 'error');
01073         if ($this->mode & PEAR_ERROR_CALLBACK) {
01074             if (is_array($this->callback)) {
01075                 $callback = (is_object($this->callback[0]) ?
01076                     strtolower(get_class($this->callback[0])) :
01077                     $this->callback[0]) . '::' .
01078                     $this->callback[1];
01079             } else {
01080                 $callback = $this->callback;
01081             }
01082             return sprintf('[%s: message="%s" code=%d mode=callback '.
01083                            'callback=%s prefix="%s" info="%s"]',
01084                            strtolower(get_class($this)), $this->message, $this->code,
01085                            $callback, $this->error_message_prefix,
01086                            $this->userinfo);
01087         }
01088         if ($this->mode & PEAR_ERROR_PRINT) {
01089             $modes[] = 'print';
01090         }
01091         if ($this->mode & PEAR_ERROR_TRIGGER) {
01092             $modes[] = 'trigger';
01093         }
01094         if ($this->mode & PEAR_ERROR_DIE) {
01095             $modes[] = 'die';
01096         }
01097         if ($this->mode & PEAR_ERROR_RETURN) {
01098             $modes[] = 'return';
01099         }
01100         return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
01101                        'prefix="%s" info="%s"]',
01102                        strtolower(get_class($this)), $this->message, $this->code,
01103                        implode("|", $modes), $levels[$this->level],
01104                        $this->error_message_prefix,
01105                        $this->userinfo);
01106     }
01107 
01108     // }}}
01109 }
01110 
01111 /*
01112  * Local Variables:
01113  * mode: php
01114  * tab-width: 4
01115  * c-basic-offset: 4
01116  * End:
01117  */
01118 ?>
 All Data Structures Namespaces Files Functions Variables Enumerations