Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/*** Error Stack Implementation** This is an incredibly simple implementation of a very complex error handling* facility. It contains the ability* to track multiple errors from multiple packages simultaneously. In addition,* it can track errors of many levels, save data along with the error, context* information such as the exact file, line number, class and function that* generated the error, and if necessary, it can raise a traditional PEAR_Error.* It has built-in support for PEAR::Log, to log errors as they occur** Since version 0.2alpha, it is also possible to selectively ignore errors,* through the use of an error callback, see {@link pushCallback()}** Since version 0.3alpha, it is possible to specify the exception class* returned from {@link push()}** Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can* still be done quite handily in an error callback or by manipulating the returned array* @category Debugging* @package PEAR_ErrorStack* @author Greg Beaver <cellog@php.net>* @copyright 2004-2006 Greg Beaver* @license http://www.php.net/license/3_0.txt PHP License 3.0* @version CVS: $Id: ErrorStack.php,v 1.26 2006/10/31 02:54:40 cellog Exp $* @link http://pear.php.net/package/PEAR_ErrorStack*//*** Singleton storage** Format:* <pre>* array(* 'package1' => PEAR_ErrorStack object,* 'package2' => PEAR_ErrorStack object,* ...* )* </pre>* @access private* @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON']*/$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array();/*** Global error callback (default)** This is only used if set to non-false. * is the default callback for* all packages, whereas specific packages may set a default callback* for all instances, regardless of whether they are a singleton or not.** To exclude non-singletons, only set the local callback for the singleton* @see PEAR_ErrorStack::setDefaultCallback()* @access private* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']*/$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array('*' => false,);/*** Global Log object (default)** This is only used if set to non-false. Use to set a default log object for* all stacks, regardless of instantiation order or location* @see PEAR_ErrorStack::setDefaultLogger()* @access private* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']*/$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false;/*** Global Overriding Callback** This callback will override any error callbacks that specific loggers have set.* Use with EXTREME caution* @see PEAR_ErrorStack::staticPushCallback()* @access private* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']*/$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();/**#@+* One of four possible return values from the error Callback* @see PEAR_ErrorStack::_errorCallback()*//*** If this is returned, then the error will be both pushed onto the stack* and logged.*/define('PEAR_ERRORSTACK_PUSHANDLOG', 1);/*** If this is returned, then the error will only be pushed onto the stack,* and not logged.*/define('PEAR_ERRORSTACK_PUSH', 2);/*** If this is returned, then the error will only be logged, but not pushed* onto the error stack.*/define('PEAR_ERRORSTACK_LOG', 3);/*** If this is returned, then the error is completely ignored.*/define('PEAR_ERRORSTACK_IGNORE', 4);/*** If this is returned, then the error is logged and die() is called.*/define('PEAR_ERRORSTACK_DIE', 5);/**#@-*//*** Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in* the singleton method.*/define('PEAR_ERRORSTACK_ERR_NONCLASS', 1);/*** Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()}* that has no __toString() method*/define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);/*** Error Stack Implementation** Usage:* <code>* // global error stack* $global_stack = &PEAR_ErrorStack::singleton('MyPackage');* // local error stack* $local_stack = new PEAR_ErrorStack('MyPackage');* </code>* @author Greg Beaver <cellog@php.net>* @version 1.5.1* @package PEAR_ErrorStack* @category Debugging* @copyright 2004-2006 Greg Beaver* @license http://www.php.net/license/3_0.txt PHP License 3.0* @version CVS: $Id: ErrorStack.php,v 1.26 2006/10/31 02:54:40 cellog Exp $* @link http://pear.php.net/package/PEAR_ErrorStack*/class PEAR_ErrorStack {/*** Errors are stored in the order that they are pushed on the stack.* @since 0.4alpha Errors are no longer organized by error level.* This renders pop() nearly unusable, and levels could be more easily* handled in a callback anyway* @var array* @access private*/var $_errors = array();/*** Storage of errors by level.** Allows easy retrieval and deletion of only errors from a particular level* @since PEAR 1.4.0dev* @var array* @access private*/var $_errorsByLevel = array();/*** Package name this error stack represents* @var string* @access protected*/var $_package;/*** Determines whether a PEAR_Error is thrown upon every error addition* @var boolean* @access private*/var $_compat = false;/*** If set to a valid callback, this will be used to generate the error* message from the error code, otherwise the message passed in will be* used* @var false|string|array* @access private*/var $_msgCallback = false;/*** If set to a valid callback, this will be used to generate the error* context for an error. For PHP-related errors, this will be a file* and line number as retrieved from debug_backtrace(), but can be* customized for other purposes. The error might actually be in a separate* configuration file, or in a database query.* @var false|string|array* @access protected*/var $_contextCallback = false;/*** If set to a valid callback, this will be called every time an error* is pushed onto the stack. The return value will be used to determine* whether to allow an error to be pushed or logged.** The return value must be one an PEAR_ERRORSTACK_* constant* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG* @var false|string|array* @access protected*/var $_errorCallback = array();/*** PEAR::Log object for logging errors* @var false|Log* @access protected*/var $_logger = false;/*** Error messages - designed to be overridden* @var array* @abstract*/var $_errorMsgs = array();/*** Set up a new error stack** @param string $package name of the package this error stack represents* @param callback $msgCallback callback used for error message generation* @param callback $contextCallback callback used for context generation,* defaults to {@link getFileLine()}* @param boolean $throwPEAR_Error*/function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false,$throwPEAR_Error = false){$this->_package = $package;$this->setMessageCallback($msgCallback);$this->setContextCallback($contextCallback);$this->_compat = $throwPEAR_Error;}/*** Return a single error stack for this package.** Note that all parameters are ignored if the stack for package $package* has already been instantiated* @param string $package name of the package this error stack represents* @param callback $msgCallback callback used for error message generation* @param callback $contextCallback callback used for context generation,* defaults to {@link getFileLine()}* @param boolean $throwPEAR_Error* @param string $stackClass class to instantiate* @static* @return PEAR_ErrorStack*/function &singleton($package, $msgCallback = false, $contextCallback = false,$throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack'){if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];}if (!class_exists($stackClass)) {if (function_exists('debug_backtrace')) {$trace = debug_backtrace();}PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS,'exception', array('stackclass' => $stackClass),'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',false, $trace);}$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];}/*** Internal error handler for PEAR_ErrorStack class** Dies if the error is an exception (and would have died anyway)* @access private*/function _handleError($err){if ($err['level'] == 'exception') {$message = $err['message'];if (isset($_SERVER['REQUEST_URI'])) {echo '<br />';} else {echo "\n";}var_dump($err['context']);die($message);}}/*** Set up a PEAR::Log object for all error stacks that don't have one* @param Log $log* @static*/function setDefaultLogger(&$log){if (is_object($log) && method_exists($log, 'log') ) {$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;} elseif (is_callable($log)) {$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;}}/*** Set up a PEAR::Log object for this error stack* @param Log $log*/function setLogger(&$log){if (is_object($log) && method_exists($log, 'log') ) {$this->_logger = &$log;} elseif (is_callable($log)) {$this->_logger = &$log;}}/*** Set an error code => error message mapping callback** This method sets the callback that can be used to generate error* messages for any instance* @param array|string Callback function/method*/function setMessageCallback($msgCallback){if (!$msgCallback) {$this->_msgCallback = array(&$this, 'getErrorMessage');} else {if (is_callable($msgCallback)) {$this->_msgCallback = $msgCallback;}}}/*** Get an error code => error message mapping callback** This method returns the current callback that can be used to generate error* messages* @return array|string|false Callback function/method or false if none*/function getMessageCallback(){return $this->_msgCallback;}/*** Sets a default callback to be used by all error stacks** This method sets the callback that can be used to generate error* messages for a singleton* @param array|string Callback function/method* @param string Package name, or false for all packages* @static*/function setDefaultCallback($callback = false, $package = false){if (!is_callable($callback)) {$callback = false;}$package = $package ? $package : '*';$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback;}/*** Set a callback that generates context information (location of error) for an error stack** This method sets the callback that can be used to generate context* information for an error. Passing in NULL will disable context generation* and remove the expensive call to debug_backtrace()* @param array|string|null Callback function/method*/function setContextCallback($contextCallback){if ($contextCallback === null) {return $this->_contextCallback = false;}if (!$contextCallback) {$this->_contextCallback = array(&$this, 'getFileLine');} else {if (is_callable($contextCallback)) {$this->_contextCallback = $contextCallback;}}}/*** Set an error Callback* If set to a valid callback, this will be called every time an error* is pushed onto the stack. The return value will be used to determine* whether to allow an error to be pushed or logged.** The return value must be one of the ERRORSTACK_* constants.** This functionality can be used to emulate PEAR's pushErrorHandling, and* the PEAR_ERROR_CALLBACK mode, without affecting the integrity of* the error stack or logging* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG* @see popCallback()* @param string|array $cb*/function pushCallback($cb){array_push($this->_errorCallback, $cb);}/*** Remove a callback from the error callback stack* @see pushCallback()* @return array|string|false*/function popCallback(){if (!count($this->_errorCallback)) {return false;}return array_pop($this->_errorCallback);}/*** Set a temporary overriding error callback for every package error stack** Use this to temporarily disable all existing callbacks (can be used* to emulate the @ operator, for instance)* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG* @see staticPopCallback(), pushCallback()* @param string|array $cb* @static*/function staticPushCallback($cb){array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);}/*** Remove a temporary overriding error callback* @see staticPushCallback()* @return array|string|false* @static*/function staticPopCallback(){$ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();}return $ret;}/*** Add an error to the stack** If the message generator exists, it is called with 2 parameters.* - the current Error Stack object* - an array that is in the same format as an error. Available indices* are 'code', 'package', 'time', 'params', 'level', and 'context'** Next, if the error should contain context information, this is* handled by the context grabbing method.* Finally, the error is pushed onto the proper error stack* @param int $code Package-specific error code* @param string $level Error level. This is NOT spell-checked* @param array $params associative array of error parameters* @param string $msg Error message, or a portion of it if the message* is to be generated* @param array $repackage If this error re-packages an error pushed by* another package, place the array returned from* {@link pop()} in this parameter* @param array $backtrace Protected parameter: use this to pass in the* {@link debug_backtrace()} that should be used* to find error context* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also* thrown. If a PEAR_Error is returned, the userinfo* property is set to the following array:** <code>* array(* 'code' => $code,* 'params' => $params,* 'package' => $this->_package,* 'level' => $level,* 'time' => time(),* 'context' => $context,* 'message' => $msg,* //['repackage' => $err] repackaged error array/Exception class* );* </code>** Normally, the previous array is returned.*/function push($code, $level = 'error', $params = array(), $msg = false,$repackage = false, $backtrace = false){$context = false;// grab error contextif ($this->_contextCallback) {if (!$backtrace) {$backtrace = debug_backtrace();}$context = call_user_func($this->_contextCallback, $code, $params, $backtrace);}// save error$time = explode(' ', microtime());$time = $time[1] + $time[0];$err = array('code' => $code,'params' => $params,'package' => $this->_package,'level' => $level,'time' => $time,'context' => $context,'message' => $msg,);if ($repackage) {$err['repackage'] = $repackage;}// set up the error message, if necessaryif ($this->_msgCallback) {$msg = call_user_func_array($this->_msgCallback,array(&$this, $err));$err['message'] = $msg;}$push = $log = true;$die = false;// try the overriding callback first$callback = $this->staticPopCallback();if ($callback) {$this->staticPushCallback($callback);}if (!is_callable($callback)) {// try the local callback next$callback = $this->popCallback();if (is_callable($callback)) {$this->pushCallback($callback);} else {// try the default callback$callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ?$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] :$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*'];}}if (is_callable($callback)) {switch(call_user_func($callback, $err)){case PEAR_ERRORSTACK_IGNORE:return $err;break;case PEAR_ERRORSTACK_PUSH:$log = false;break;case PEAR_ERRORSTACK_LOG:$push = false;break;case PEAR_ERRORSTACK_DIE:$die = true;break;// anything else returned has the same effect as pushandlog}}if ($push) {array_unshift($this->_errors, $err);if (!isset($this->_errorsByLevel[$err['level']])) {$this->_errorsByLevel[$err['level']] = array();}$this->_errorsByLevel[$err['level']][] = &$this->_errors[0];}if ($log) {if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) {$this->_log($err);}}if ($die) {die();}if ($this->_compat && $push) {return $this->raiseError($msg, $code, null, null, $err);}return $err;}/*** Static version of {@link push()}** @param string $package Package name this error belongs to* @param int $code Package-specific error code* @param string $level Error level. This is NOT spell-checked* @param array $params associative array of error parameters* @param string $msg Error message, or a portion of it if the message* is to be generated* @param array $repackage If this error re-packages an error pushed by* another package, place the array returned from* {@link pop()} in this parameter* @param array $backtrace Protected parameter: use this to pass in the* {@link debug_backtrace()} that should be used* to find error context* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also* thrown. see docs for {@link push()}* @static*/function staticPush($package, $code, $level = 'error', $params = array(),$msg = false, $repackage = false, $backtrace = false){$s = &PEAR_ErrorStack::singleton($package);if ($s->_contextCallback) {if (!$backtrace) {if (function_exists('debug_backtrace')) {$backtrace = debug_backtrace();}}}return $s->push($code, $level, $params, $msg, $repackage, $backtrace);}/*** Log an error using PEAR::Log* @param array $err Error array* @param array $levels Error level => Log constant map* @access protected*/function _log($err){if ($this->_logger) {$logger = &$this->_logger;} else {$logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'];}if (is_a($logger, 'Log')) {$levels = array('exception' => PEAR_LOG_CRIT,'alert' => PEAR_LOG_ALERT,'critical' => PEAR_LOG_CRIT,'error' => PEAR_LOG_ERR,'warning' => PEAR_LOG_WARNING,'notice' => PEAR_LOG_NOTICE,'info' => PEAR_LOG_INFO,'debug' => PEAR_LOG_DEBUG);if (isset($levels[$err['level']])) {$level = $levels[$err['level']];} else {$level = PEAR_LOG_INFO;}$logger->log($err['message'], $level, $err);} else { // support non-standard logscall_user_func($logger, $err);}}/*** Pop an error off of the error stack** @return false|array* @since 0.4alpha it is no longer possible to specify a specific error* level to return - the last error pushed will be returned, instead*/function pop(){$err = @array_shift($this->_errors);if (!is_null($err)) {@array_pop($this->_errorsByLevel[$err['level']]);if (!count($this->_errorsByLevel[$err['level']])) {unset($this->_errorsByLevel[$err['level']]);}}return $err;}/*** Pop an error off of the error stack, static method** @param string package name* @return boolean* @since PEAR1.5.0a1*/function staticPop($package){if ($package) {if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {return false;}return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();}}/*** Determine whether there are any errors on the stack* @param string|array Level name. Use to determine if any errors* of level (string), or levels (array) have been pushed* @return boolean*/function hasErrors($level = false){if ($level) {return isset($this->_errorsByLevel[$level]);}return count($this->_errors);}/*** Retrieve all errors since last purge** @param boolean set in order to empty the error stack* @param string level name, to return only errors of a particular severity* @return array*/function getErrors($purge = false, $level = false){if (!$purge) {if ($level) {if (!isset($this->_errorsByLevel[$level])) {return array();} else {return $this->_errorsByLevel[$level];}} else {return $this->_errors;}}if ($level) {$ret = $this->_errorsByLevel[$level];foreach ($this->_errorsByLevel[$level] as $i => $unused) {// entries are references to the $_errors array$this->_errorsByLevel[$level][$i] = false;}// array_filter removes all entries === false$this->_errors = array_filter($this->_errors);unset($this->_errorsByLevel[$level]);return $ret;}$ret = $this->_errors;$this->_errors = array();$this->_errorsByLevel = array();return $ret;}/*** Determine whether there are any errors on a single error stack, or on any error stack** The optional parameter can be used to test the existence of any errors without the need of* singleton instantiation* @param string|false Package name to check for errors* @param string Level name to check for a particular severity* @return boolean* @static*/function staticHasErrors($package = false, $level = false){if ($package) {if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {return false;}return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level);}foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {if ($obj->hasErrors($level)) {return true;}}return false;}/*** Get a list of all errors since last purge, organized by package* @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be* @param boolean $purge Set to purge the error stack of existing errors* @param string $level Set to a level name in order to retrieve only errors of a particular level* @param boolean $merge Set to return a flat array, not organized by package* @param array $sortfunc Function used to sort a merged array - default* sorts by time, and should be good for most cases* @static* @return array*/function staticGetErrors($purge = false, $level = false, $merge = false,$sortfunc = array('PEAR_ErrorStack', '_sortErrors')){$ret = array();if (!is_callable($sortfunc)) {$sortfunc = array('PEAR_ErrorStack', '_sortErrors');}foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {$test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level);if ($test) {if ($merge) {$ret = array_merge($ret, $test);} else {$ret[$package] = $test;}}}if ($merge) {usort($ret, $sortfunc);}return $ret;}/*** Error sorting function, sorts by time* @access private*/function _sortErrors($a, $b){if ($a['time'] == $b['time']) {return 0;}if ($a['time'] < $b['time']) {return 1;}return -1;}/*** Standard file/line number/function/class context callback** This function uses a backtrace generated from {@link debug_backtrace()}* and so will not work at all in PHP < 4.3.0. The frame should* reference the frame that contains the source of the error.* @return array|false either array('file' => file, 'line' => line,* 'function' => function name, 'class' => class name) or* if this doesn't work, then false* @param unused* @param integer backtrace frame.* @param array Results of debug_backtrace()* @static*/function getFileLine($code, $params, $backtrace = null){if ($backtrace === null) {return false;}$frame = 0;$functionframe = 1;if (!isset($backtrace[1])) {$functionframe = 0;} else {while (isset($backtrace[$functionframe]['function']) &&$backtrace[$functionframe]['function'] == 'eval' &&isset($backtrace[$functionframe + 1])) {$functionframe++;}}if (isset($backtrace[$frame])) {if (!isset($backtrace[$frame]['file'])) {$frame++;}$funcbacktrace = $backtrace[$functionframe];$filebacktrace = $backtrace[$frame];$ret = array('file' => $filebacktrace['file'],'line' => $filebacktrace['line']);// rearrange for eval'd code or create function errorsif (strpos($filebacktrace['file'], '(') &&preg_match(';^(.*?)\((\d+)\) : (.*?)$;', $filebacktrace['file'],$matches)) {$ret['file'] = $matches[1];$ret['line'] = $matches[2] + 0;}if (isset($funcbacktrace['function']) && isset($backtrace[1])) {if ($funcbacktrace['function'] != 'eval') {if ($funcbacktrace['function'] == '__lambda_func') {$ret['function'] = 'create_function() code';} else {$ret['function'] = $funcbacktrace['function'];}}}if (isset($funcbacktrace['class']) && isset($backtrace[1])) {$ret['class'] = $funcbacktrace['class'];}return $ret;}return false;}/*** Standard error message generation callback** This method may also be called by a custom error message generator* to fill in template values from the params array, simply* set the third parameter to the error message template string to use** The special variable %__msg% is reserved: use it only to specify* where a message passed in by the user should be placed in the template,* like so:** Error message: %msg% - internal error** If the message passed like so:** <code>* $stack->push(ERROR_CODE, 'error', array(), 'server error 500');* </code>** The returned error message will be "Error message: server error 500 -* internal error"* @param PEAR_ErrorStack* @param array* @param string|false Pre-generated error message template* @static* @return string*/function getErrorMessage(&$stack, $err, $template = false){if ($template) {$mainmsg = $template;} else {$mainmsg = $stack->getErrorMessageTemplate($err['code']);}$mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);if (is_array($err['params']) && count($err['params'])) {foreach ($err['params'] as $name => $val) {if (is_array($val)) {// @ is needed in case $val is a multi-dimensional array$val = @implode(', ', $val);}if (is_object($val)) {if (method_exists($val, '__toString')) {$val = $val->__toString();} else {PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING,'warning', array('obj' => get_class($val)),'object %obj% passed into getErrorMessage, but has no __toString() method');$val = 'Object';}}$mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);}}return $mainmsg;}/*** Standard Error Message Template generator from code* @return string*/function getErrorMessageTemplate($code){if (!isset($this->_errorMsgs[$code])) {return '%__msg%';}return $this->_errorMsgs[$code];}/*** Set the Error Message Template array** The array format must be:* <pre>* array(error code => 'message template',...)* </pre>** Error message parameters passed into {@link push()} will be used as input* for the error message. If the template is 'message %foo% was %bar%', and the* parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will* be 'message one was six'* @return string*/function setErrorMessageTemplate($template){$this->_errorMsgs = $template;}/*** emulate PEAR::raiseError()** @return PEAR_Error*/function raiseError(){require_once 'PEAR.php';$args = func_get_args();return call_user_func_array(array('PEAR', 'raiseError'), $args);}}$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack');$stack->pushCallback(array('PEAR_ErrorStack', '_handleError'));?>