3 * Error Stack Implementation
5 * This is an incredibly simple implementation of a very complex error handling
6 * facility. It contains the ability
7 * to track multiple errors from multiple packages simultaneously. In addition,
8 * it can track errors of many levels, save data along with the error, context
9 * information such as the exact file, line number, class and function that
10 * generated the error, and if necessary, it can raise a traditional PEAR_Error.
11 * It has built-in support for PEAR::Log, to log errors as they occur
13 * Since version 0.2alpha, it is also possible to selectively ignore errors,
14 * through the use of an error callback, see {@link pushCallback()}
16 * Since version 0.3alpha, it is possible to specify the exception class
17 * returned from {@link push()}
19 * Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can
20 * still be done quite handily in an error callback or by manipulating the returned array
22 * @package PEAR_ErrorStack
23 * @author Greg Beaver <cellog@php.net>
24 * @copyright 2004-2008 Greg Beaver
25 * @license http://opensource.org/licenses/bsd-license.php New BSD License
26 * @version CVS: $Id: ErrorStack.php 307683 2011-01-23 21:56:12Z dufuz $
27 * @link http://pear.php.net/package/PEAR_ErrorStack
36 * 'package1' => PEAR_ErrorStack object,
37 * 'package2' => PEAR_ErrorStack object,
42 * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON']
44 $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array();
47 * Global error callback (default)
49 * This is only used if set to non-false. * is the default callback for
50 * all packages, whereas specific packages may set a default callback
51 * for all instances, regardless of whether they are a singleton or not.
53 * To exclude non-singletons, only set the local callback for the singleton
54 * @see PEAR_ErrorStack::setDefaultCallback()
56 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']
58 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array(
63 * Global Log object (default)
65 * This is only used if set to non-false. Use to set a default log object for
66 * all stacks, regardless of instantiation order or location
67 * @see PEAR_ErrorStack::setDefaultLogger()
69 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
71 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false;
74 * Global Overriding Callback
76 * This callback will override any error callbacks that specific loggers have set.
77 * Use with EXTREME caution
78 * @see PEAR_ErrorStack::staticPushCallback()
80 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
82 $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
85 * One of four possible return values from the error Callback
86 * @see PEAR_ErrorStack::_errorCallback()
89 * If this is returned, then the error will be both pushed onto the stack
92 define('PEAR_ERRORSTACK_PUSHANDLOG', 1);
94 * If this is returned, then the error will only be pushed onto the stack,
97 define('PEAR_ERRORSTACK_PUSH', 2);
99 * If this is returned, then the error will only be logged, but not pushed
100 * onto the error stack.
102 define('PEAR_ERRORSTACK_LOG', 3);
104 * If this is returned, then the error is completely ignored.
106 define('PEAR_ERRORSTACK_IGNORE', 4);
108 * If this is returned, then the error is logged and die() is called.
110 define('PEAR_ERRORSTACK_DIE', 5);
114 * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in
115 * the singleton method.
117 define('PEAR_ERRORSTACK_ERR_NONCLASS', 1);
120 * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()}
121 * that has no __toString() method
123 define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
125 * Error Stack Implementation
129 * // global error stack
130 * $global_stack = &PEAR_ErrorStack::singleton('MyPackage');
131 * // local error stack
132 * $local_stack = new PEAR_ErrorStack('MyPackage');
134 * @author Greg Beaver <cellog@php.net>
136 * @package PEAR_ErrorStack
137 * @category Debugging
138 * @copyright 2004-2008 Greg Beaver
139 * @license http://opensource.org/licenses/bsd-license.php New BSD License
140 * @version CVS: $Id: ErrorStack.php 307683 2011-01-23 21:56:12Z dufuz $
141 * @link http://pear.php.net/package/PEAR_ErrorStack
143 class PEAR_ErrorStack {
145 * Errors are stored in the order that they are pushed on the stack.
146 * @since 0.4alpha Errors are no longer organized by error level.
147 * This renders pop() nearly unusable, and levels could be more easily
148 * handled in a callback anyway
152 var $_errors = array();
155 * Storage of errors by level.
157 * Allows easy retrieval and deletion of only errors from a particular level
158 * @since PEAR 1.4.0dev
162 var $_errorsByLevel = array();
165 * Package name this error stack represents
172 * Determines whether a PEAR_Error is thrown upon every error addition
176 var $_compat = false;
179 * If set to a valid callback, this will be used to generate the error
180 * message from the error code, otherwise the message passed in will be
182 * @var false|string|array
185 var $_msgCallback = false;
188 * If set to a valid callback, this will be used to generate the error
189 * context for an error. For PHP-related errors, this will be a file
190 * and line number as retrieved from debug_backtrace(), but can be
191 * customized for other purposes. The error might actually be in a separate
192 * configuration file, or in a database query.
193 * @var false|string|array
196 var $_contextCallback = false;
199 * If set to a valid callback, this will be called every time an error
200 * is pushed onto the stack. The return value will be used to determine
201 * whether to allow an error to be pushed or logged.
203 * The return value must be one an PEAR_ERRORSTACK_* constant
204 * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
205 * @var false|string|array
208 var $_errorCallback = array();
211 * PEAR::Log object for logging errors
215 var $_logger = false;
218 * Error messages - designed to be overridden
222 var $_errorMsgs = array();
225 * Set up a new error stack
227 * @param string $package name of the package this error stack represents
228 * @param callback $msgCallback callback used for error message generation
229 * @param callback $contextCallback callback used for context generation,
230 * defaults to {@link getFileLine()}
231 * @param boolean $throwPEAR_Error
233 function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false,
234 $throwPEAR_Error = false)
236 $this->_package = $package;
237 $this->setMessageCallback($msgCallback);
238 $this->setContextCallback($contextCallback);
239 $this->_compat = $throwPEAR_Error;
243 * Return a single error stack for this package.
245 * Note that all parameters are ignored if the stack for package $package
246 * has already been instantiated
247 * @param string $package name of the package this error stack represents
248 * @param callback $msgCallback callback used for error message generation
249 * @param callback $contextCallback callback used for context generation,
250 * defaults to {@link getFileLine()}
251 * @param boolean $throwPEAR_Error
252 * @param string $stackClass class to instantiate
254 * @return PEAR_ErrorStack
256 function &singleton($package, $msgCallback = false, $contextCallback = false,
257 $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack')
259 if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
260 return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
262 if (!class_exists($stackClass)) {
263 if (function_exists('debug_backtrace')) {
264 $trace = debug_backtrace();
266 PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS,
267 'exception', array('stackclass' => $stackClass),
268 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
271 $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =
272 new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);
274 return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
278 * Internal error handler for PEAR_ErrorStack class
280 * Dies if the error is an exception (and would have died anyway)
283 function _handleError($err)
285 if ($err['level'] == 'exception') {
286 $message = $err['message'];
287 if (isset($_SERVER['REQUEST_URI'])) {
292 var_dump($err['context']);
298 * Set up a PEAR::Log object for all error stacks that don't have one
302 function setDefaultLogger(&$log)
304 if (is_object($log) && method_exists($log, 'log') ) {
305 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
306 } elseif (is_callable($log)) {
307 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
312 * Set up a PEAR::Log object for this error stack
315 function setLogger(&$log)
317 if (is_object($log) && method_exists($log, 'log') ) {
318 $this->_logger = &$log;
319 } elseif (is_callable($log)) {
320 $this->_logger = &$log;
325 * Set an error code => error message mapping callback
327 * This method sets the callback that can be used to generate error
328 * messages for any instance
329 * @param array|string Callback function/method
331 function setMessageCallback($msgCallback)
334 $this->_msgCallback = array(&$this, 'getErrorMessage');
336 if (is_callable($msgCallback)) {
337 $this->_msgCallback = $msgCallback;
343 * Get an error code => error message mapping callback
345 * This method returns the current callback that can be used to generate error
347 * @return array|string|false Callback function/method or false if none
349 function getMessageCallback()
351 return $this->_msgCallback;
355 * Sets a default callback to be used by all error stacks
357 * This method sets the callback that can be used to generate error
358 * messages for a singleton
359 * @param array|string Callback function/method
360 * @param string Package name, or false for all packages
363 function setDefaultCallback($callback = false, $package = false)
365 if (!is_callable($callback)) {
368 $package = $package ? $package : '*';
369 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback;
373 * Set a callback that generates context information (location of error) for an error stack
375 * This method sets the callback that can be used to generate context
376 * information for an error. Passing in NULL will disable context generation
377 * and remove the expensive call to debug_backtrace()
378 * @param array|string|null Callback function/method
380 function setContextCallback($contextCallback)
382 if ($contextCallback === null) {
383 return $this->_contextCallback = false;
385 if (!$contextCallback) {
386 $this->_contextCallback = array(&$this, 'getFileLine');
388 if (is_callable($contextCallback)) {
389 $this->_contextCallback = $contextCallback;
395 * Set an error Callback
396 * If set to a valid callback, this will be called every time an error
397 * is pushed onto the stack. The return value will be used to determine
398 * whether to allow an error to be pushed or logged.
400 * The return value must be one of the ERRORSTACK_* constants.
402 * This functionality can be used to emulate PEAR's pushErrorHandling, and
403 * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of
404 * the error stack or logging
405 * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
407 * @param string|array $cb
409 function pushCallback($cb)
411 array_push($this->_errorCallback, $cb);
415 * Remove a callback from the error callback stack
416 * @see pushCallback()
417 * @return array|string|false
419 function popCallback()
421 if (!count($this->_errorCallback)) {
424 return array_pop($this->_errorCallback);
428 * Set a temporary overriding error callback for every package error stack
430 * Use this to temporarily disable all existing callbacks (can be used
431 * to emulate the @ operator, for instance)
432 * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
433 * @see staticPopCallback(), pushCallback()
434 * @param string|array $cb
437 function staticPushCallback($cb)
439 array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
443 * Remove a temporary overriding error callback
444 * @see staticPushCallback()
445 * @return array|string|false
448 function staticPopCallback()
450 $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
451 if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
452 $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
458 * Add an error to the stack
460 * If the message generator exists, it is called with 2 parameters.
461 * - the current Error Stack object
462 * - an array that is in the same format as an error. Available indices
463 * are 'code', 'package', 'time', 'params', 'level', and 'context'
465 * Next, if the error should contain context information, this is
466 * handled by the context grabbing method.
467 * Finally, the error is pushed onto the proper error stack
468 * @param int $code Package-specific error code
469 * @param string $level Error level. This is NOT spell-checked
470 * @param array $params associative array of error parameters
471 * @param string $msg Error message, or a portion of it if the message
473 * @param array $repackage If this error re-packages an error pushed by
474 * another package, place the array returned from
475 * {@link pop()} in this parameter
476 * @param array $backtrace Protected parameter: use this to pass in the
477 * {@link debug_backtrace()} that should be used
478 * to find error context
479 * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
480 * thrown. If a PEAR_Error is returned, the userinfo
481 * property is set to the following array:
486 * 'params' => $params,
487 * 'package' => $this->_package,
490 * 'context' => $context,
492 * //['repackage' => $err] repackaged error array/Exception class
496 * Normally, the previous array is returned.
498 function push($code, $level = 'error', $params = array(), $msg = false,
499 $repackage = false, $backtrace = false)
502 // grab error context
503 if ($this->_contextCallback) {
505 $backtrace = debug_backtrace();
507 $context = call_user_func($this->_contextCallback, $code, $params, $backtrace);
511 $time = explode(' ', microtime());
512 $time = $time[1] + $time[0];
516 'package' => $this->_package,
519 'context' => $context,
524 $err['repackage'] = $repackage;
527 // set up the error message, if necessary
528 if ($this->_msgCallback) {
529 $msg = call_user_func_array($this->_msgCallback,
530 array(&$this, $err));
531 $err['message'] = $msg;
535 // try the overriding callback first
536 $callback = $this->staticPopCallback();
538 $this->staticPushCallback($callback);
540 if (!is_callable($callback)) {
541 // try the local callback next
542 $callback = $this->popCallback();
543 if (is_callable($callback)) {
544 $this->pushCallback($callback);
546 // try the default callback
547 $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ?
548 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] :
549 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*'];
552 if (is_callable($callback)) {
553 switch(call_user_func($callback, $err)){
554 case PEAR_ERRORSTACK_IGNORE:
557 case PEAR_ERRORSTACK_PUSH:
560 case PEAR_ERRORSTACK_LOG:
563 case PEAR_ERRORSTACK_DIE:
566 // anything else returned has the same effect as pushandlog
570 array_unshift($this->_errors, $err);
571 if (!isset($this->_errorsByLevel[$err['level']])) {
572 $this->_errorsByLevel[$err['level']] = array();
574 $this->_errorsByLevel[$err['level']][] = &$this->_errors[0];
577 if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) {
584 if ($this->_compat && $push) {
585 return $this->raiseError($msg, $code, null, null, $err);
591 * Static version of {@link push()}
593 * @param string $package Package name this error belongs to
594 * @param int $code Package-specific error code
595 * @param string $level Error level. This is NOT spell-checked
596 * @param array $params associative array of error parameters
597 * @param string $msg Error message, or a portion of it if the message
599 * @param array $repackage If this error re-packages an error pushed by
600 * another package, place the array returned from
601 * {@link pop()} in this parameter
602 * @param array $backtrace Protected parameter: use this to pass in the
603 * {@link debug_backtrace()} that should be used
604 * to find error context
605 * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
606 * thrown. see docs for {@link push()}
609 function staticPush($package, $code, $level = 'error', $params = array(),
610 $msg = false, $repackage = false, $backtrace = false)
612 $s = &PEAR_ErrorStack::singleton($package);
613 if ($s->_contextCallback) {
615 if (function_exists('debug_backtrace')) {
616 $backtrace = debug_backtrace();
620 return $s->push($code, $level, $params, $msg, $repackage, $backtrace);
624 * Log an error using PEAR::Log
625 * @param array $err Error array
626 * @param array $levels Error level => Log constant map
631 if ($this->_logger) {
632 $logger = &$this->_logger;
634 $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'];
636 if (is_a($logger, 'Log')) {
638 'exception' => PEAR_LOG_CRIT,
639 'alert' => PEAR_LOG_ALERT,
640 'critical' => PEAR_LOG_CRIT,
641 'error' => PEAR_LOG_ERR,
642 'warning' => PEAR_LOG_WARNING,
643 'notice' => PEAR_LOG_NOTICE,
644 'info' => PEAR_LOG_INFO,
645 'debug' => PEAR_LOG_DEBUG);
646 if (isset($levels[$err['level']])) {
647 $level = $levels[$err['level']];
649 $level = PEAR_LOG_INFO;
651 $logger->log($err['message'], $level, $err);
652 } else { // support non-standard logs
653 call_user_func($logger, $err);
659 * Pop an error off of the error stack
661 * @return false|array
662 * @since 0.4alpha it is no longer possible to specify a specific error
663 * level to return - the last error pushed will be returned, instead
667 $err = @array_shift($this->_errors);
668 if (!is_null($err)) {
669 @array_pop($this->_errorsByLevel[$err['level']]);
670 if (!count($this->_errorsByLevel[$err['level']])) {
671 unset($this->_errorsByLevel[$err['level']]);
678 * Pop an error off of the error stack, static method
680 * @param string package name
684 function staticPop($package)
687 if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
690 return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
695 * Determine whether there are any errors on the stack
696 * @param string|array Level name. Use to determine if any errors
697 * of level (string), or levels (array) have been pushed
700 function hasErrors($level = false)
703 return isset($this->_errorsByLevel[$level]);
705 return count($this->_errors);
709 * Retrieve all errors since last purge
711 * @param boolean set in order to empty the error stack
712 * @param string level name, to return only errors of a particular severity
715 function getErrors($purge = false, $level = false)
719 if (!isset($this->_errorsByLevel[$level])) {
722 return $this->_errorsByLevel[$level];
725 return $this->_errors;
729 $ret = $this->_errorsByLevel[$level];
730 foreach ($this->_errorsByLevel[$level] as $i => $unused) {
731 // entries are references to the $_errors array
732 $this->_errorsByLevel[$level][$i] = false;
734 // array_filter removes all entries === false
735 $this->_errors = array_filter($this->_errors);
736 unset($this->_errorsByLevel[$level]);
739 $ret = $this->_errors;
740 $this->_errors = array();
741 $this->_errorsByLevel = array();
746 * Determine whether there are any errors on a single error stack, or on any error stack
748 * The optional parameter can be used to test the existence of any errors without the need of
749 * singleton instantiation
750 * @param string|false Package name to check for errors
751 * @param string Level name to check for a particular severity
755 function staticHasErrors($package = false, $level = false)
758 if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
761 return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level);
763 foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
764 if ($obj->hasErrors($level)) {
772 * Get a list of all errors since last purge, organized by package
773 * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be
774 * @param boolean $purge Set to purge the error stack of existing errors
775 * @param string $level Set to a level name in order to retrieve only errors of a particular level
776 * @param boolean $merge Set to return a flat array, not organized by package
777 * @param array $sortfunc Function used to sort a merged array - default
778 * sorts by time, and should be good for most cases
782 function staticGetErrors($purge = false, $level = false, $merge = false,
783 $sortfunc = array('PEAR_ErrorStack', '_sortErrors'))
786 if (!is_callable($sortfunc)) {
787 $sortfunc = array('PEAR_ErrorStack', '_sortErrors');
789 foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
790 $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level);
793 $ret = array_merge($ret, $test);
795 $ret[$package] = $test;
800 usort($ret, $sortfunc);
806 * Error sorting function, sorts by time
809 function _sortErrors($a, $b)
811 if ($a['time'] == $b['time']) {
814 if ($a['time'] < $b['time']) {
821 * Standard file/line number/function/class context callback
823 * This function uses a backtrace generated from {@link debug_backtrace()}
824 * and so will not work at all in PHP < 4.3.0. The frame should
825 * reference the frame that contains the source of the error.
826 * @return array|false either array('file' => file, 'line' => line,
827 * 'function' => function name, 'class' => class name) or
828 * if this doesn't work, then false
830 * @param integer backtrace frame.
831 * @param array Results of debug_backtrace()
834 function getFileLine($code, $params, $backtrace = null)
836 if ($backtrace === null) {
841 if (!isset($backtrace[1])) {
844 while (isset($backtrace[$functionframe]['function']) &&
845 $backtrace[$functionframe]['function'] == 'eval' &&
846 isset($backtrace[$functionframe + 1])) {
850 if (isset($backtrace[$frame])) {
851 if (!isset($backtrace[$frame]['file'])) {
854 $funcbacktrace = $backtrace[$functionframe];
855 $filebacktrace = $backtrace[$frame];
856 $ret = array('file' => $filebacktrace['file'],
857 'line' => $filebacktrace['line']);
858 // rearrange for eval'd code or create function errors
859 if (strpos($filebacktrace['file'], '(') &&
860 preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
862 $ret['file'] = $matches[1];
863 $ret['line'] = $matches[2] + 0;
865 if (isset($funcbacktrace['function']) && isset($backtrace[1])) {
866 if ($funcbacktrace['function'] != 'eval') {
867 if ($funcbacktrace['function'] == '__lambda_func') {
868 $ret['function'] = 'create_function() code';
870 $ret['function'] = $funcbacktrace['function'];
874 if (isset($funcbacktrace['class']) && isset($backtrace[1])) {
875 $ret['class'] = $funcbacktrace['class'];
883 * Standard error message generation callback
885 * This method may also be called by a custom error message generator
886 * to fill in template values from the params array, simply
887 * set the third parameter to the error message template string to use
889 * The special variable %__msg% is reserved: use it only to specify
890 * where a message passed in by the user should be placed in the template,
893 * Error message: %msg% - internal error
895 * If the message passed like so:
898 * $stack->push(ERROR_CODE, 'error', array(), 'server error 500');
901 * The returned error message will be "Error message: server error 500 -
903 * @param PEAR_ErrorStack
905 * @param string|false Pre-generated error message template
909 function getErrorMessage(&$stack, $err, $template = false)
912 $mainmsg = $template;
914 $mainmsg = $stack->getErrorMessageTemplate($err['code']);
916 $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);
917 if (is_array($err['params']) && count($err['params'])) {
918 foreach ($err['params'] as $name => $val) {
919 if (is_array($val)) {
920 // @ is needed in case $val is a multi-dimensional array
921 $val = @implode(', ', $val);
923 if (is_object($val)) {
924 if (method_exists($val, '__toString')) {
925 $val = $val->__toString();
927 PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING,
928 'warning', array('obj' => get_class($val)),
929 'object %obj% passed into getErrorMessage, but has no __toString() method');
933 $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
940 * Standard Error Message Template generator from code
943 function getErrorMessageTemplate($code)
945 if (!isset($this->_errorMsgs[$code])) {
948 return $this->_errorMsgs[$code];
952 * Set the Error Message Template array
954 * The array format must be:
956 * array(error code => 'message template',...)
959 * Error message parameters passed into {@link push()} will be used as input
960 * for the error message. If the template is 'message %foo% was %bar%', and the
961 * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will
962 * be 'message one was six'
965 function setErrorMessageTemplate($template)
967 $this->_errorMsgs = $template;
972 * emulate PEAR::raiseError()
976 function raiseError()
978 require_once 'PEAR.php';
979 $args = func_get_args();
980 return call_user_func_array(array('PEAR', 'raiseError'), $args);
983 $stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack');
984 $stack->pushCallback(array('PEAR_ErrorStack', '_handleError'));