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 * @link http://pear.php.net/package/PEAR_ErrorStack
35 * 'package1' => PEAR_ErrorStack object,
36 * 'package2' => PEAR_ErrorStack object,
41 * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON']
43 $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array();
46 * Global error callback (default)
48 * This is only used if set to non-false. * is the default callback for
49 * all packages, whereas specific packages may set a default callback
50 * for all instances, regardless of whether they are a singleton or not.
52 * To exclude non-singletons, only set the local callback for the singleton
53 * @see PEAR_ErrorStack::setDefaultCallback()
55 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']
57 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array(
62 * Global Log object (default)
64 * This is only used if set to non-false. Use to set a default log object for
65 * all stacks, regardless of instantiation order or location
66 * @see PEAR_ErrorStack::setDefaultLogger()
68 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
70 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false;
73 * Global Overriding Callback
75 * This callback will override any error callbacks that specific loggers have set.
76 * Use with EXTREME caution
77 * @see PEAR_ErrorStack::staticPushCallback()
79 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
81 $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
84 * One of four possible return values from the error Callback
85 * @see PEAR_ErrorStack::_errorCallback()
88 * If this is returned, then the error will be both pushed onto the stack
91 define('PEAR_ERRORSTACK_PUSHANDLOG', 1);
93 * If this is returned, then the error will only be pushed onto the stack,
96 define('PEAR_ERRORSTACK_PUSH', 2);
98 * If this is returned, then the error will only be logged, but not pushed
99 * onto the error stack.
101 define('PEAR_ERRORSTACK_LOG', 3);
103 * If this is returned, then the error is completely ignored.
105 define('PEAR_ERRORSTACK_IGNORE', 4);
107 * If this is returned, then the error is logged and die() is called.
109 define('PEAR_ERRORSTACK_DIE', 5);
113 * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in
114 * the singleton method.
116 define('PEAR_ERRORSTACK_ERR_NONCLASS', 1);
119 * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()}
120 * that has no __toString() method
122 define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
124 * Error Stack Implementation
128 * // global error stack
129 * $global_stack = &PEAR_ErrorStack::singleton('MyPackage');
130 * // local error stack
131 * $local_stack = new PEAR_ErrorStack('MyPackage');
133 * @author Greg Beaver <cellog@php.net>
135 * @package PEAR_ErrorStack
136 * @category Debugging
137 * @copyright 2004-2008 Greg Beaver
138 * @license http://opensource.org/licenses/bsd-license.php New BSD License
139 * @link http://pear.php.net/package/PEAR_ErrorStack
141 class PEAR_ErrorStack {
143 * Errors are stored in the order that they are pushed on the stack.
144 * @since 0.4alpha Errors are no longer organized by error level.
145 * This renders pop() nearly unusable, and levels could be more easily
146 * handled in a callback anyway
150 var $_errors = array();
153 * Storage of errors by level.
155 * Allows easy retrieval and deletion of only errors from a particular level
156 * @since PEAR 1.4.0dev
160 var $_errorsByLevel = array();
163 * Package name this error stack represents
170 * Determines whether a PEAR_Error is thrown upon every error addition
174 var $_compat = false;
177 * If set to a valid callback, this will be used to generate the error
178 * message from the error code, otherwise the message passed in will be
180 * @var false|string|array
183 var $_msgCallback = false;
186 * If set to a valid callback, this will be used to generate the error
187 * context for an error. For PHP-related errors, this will be a file
188 * and line number as retrieved from debug_backtrace(), but can be
189 * customized for other purposes. The error might actually be in a separate
190 * configuration file, or in a database query.
191 * @var false|string|array
194 var $_contextCallback = false;
197 * If set to a valid callback, this will be called every time an error
198 * is pushed onto the stack. The return value will be used to determine
199 * whether to allow an error to be pushed or logged.
201 * The return value must be one an PEAR_ERRORSTACK_* constant
202 * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
203 * @var false|string|array
206 var $_errorCallback = array();
209 * PEAR::Log object for logging errors
213 var $_logger = false;
216 * Error messages - designed to be overridden
220 var $_errorMsgs = array();
223 * Set up a new error stack
225 * @param string $package name of the package this error stack represents
226 * @param callback $msgCallback callback used for error message generation
227 * @param callback $contextCallback callback used for context generation,
228 * defaults to {@link getFileLine()}
229 * @param boolean $throwPEAR_Error
231 function __construct($package, $msgCallback = false, $contextCallback = false,
232 $throwPEAR_Error = false)
234 $this->_package = $package;
235 $this->setMessageCallback($msgCallback);
236 $this->setContextCallback($contextCallback);
237 $this->_compat = $throwPEAR_Error;
241 * Return a single error stack for this package.
243 * Note that all parameters are ignored if the stack for package $package
244 * has already been instantiated
245 * @param string $package name of the package this error stack represents
246 * @param callback $msgCallback callback used for error message generation
247 * @param callback $contextCallback callback used for context generation,
248 * defaults to {@link getFileLine()}
249 * @param boolean $throwPEAR_Error
250 * @param string $stackClass class to instantiate
252 * @return PEAR_ErrorStack
254 public static function &singleton(
255 $package, $msgCallback = false, $contextCallback = false,
256 $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack'
258 if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
259 return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
261 if (!class_exists($stackClass)) {
262 if (function_exists('debug_backtrace')) {
263 $trace = debug_backtrace();
265 PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS,
266 'exception', array('stackclass' => $stackClass),
267 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
270 $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =
271 new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);
273 return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
277 * Internal error handler for PEAR_ErrorStack class
279 * Dies if the error is an exception (and would have died anyway)
282 function _handleError($err)
284 if ($err['level'] == 'exception') {
285 $message = $err['message'];
286 if (isset($_SERVER['REQUEST_URI'])) {
291 var_dump($err['context']);
297 * Set up a PEAR::Log object for all error stacks that don't have one
300 public static function setDefaultLogger(&$log)
302 if (is_object($log) && method_exists($log, 'log') ) {
303 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
304 } elseif (is_callable($log)) {
305 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
310 * Set up a PEAR::Log object for this error stack
313 function setLogger(&$log)
315 if (is_object($log) && method_exists($log, 'log') ) {
316 $this->_logger = &$log;
317 } elseif (is_callable($log)) {
318 $this->_logger = &$log;
323 * Set an error code => error message mapping callback
325 * This method sets the callback that can be used to generate error
326 * messages for any instance
327 * @param array|string Callback function/method
329 function setMessageCallback($msgCallback)
332 $this->_msgCallback = array(&$this, 'getErrorMessage');
334 if (is_callable($msgCallback)) {
335 $this->_msgCallback = $msgCallback;
341 * Get an error code => error message mapping callback
343 * This method returns the current callback that can be used to generate error
345 * @return array|string|false Callback function/method or false if none
347 function getMessageCallback()
349 return $this->_msgCallback;
353 * Sets a default callback to be used by all error stacks
355 * This method sets the callback that can be used to generate error
356 * messages for a singleton
357 * @param array|string Callback function/method
358 * @param string Package name, or false for all packages
360 public static function setDefaultCallback($callback = false, $package = false)
362 if (!is_callable($callback)) {
365 $package = $package ? $package : '*';
366 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback;
370 * Set a callback that generates context information (location of error) for an error stack
372 * This method sets the callback that can be used to generate context
373 * information for an error. Passing in NULL will disable context generation
374 * and remove the expensive call to debug_backtrace()
375 * @param array|string|null Callback function/method
377 function setContextCallback($contextCallback)
379 if ($contextCallback === null) {
380 return $this->_contextCallback = false;
382 if (!$contextCallback) {
383 $this->_contextCallback = array(&$this, 'getFileLine');
385 if (is_callable($contextCallback)) {
386 $this->_contextCallback = $contextCallback;
392 * Set an error Callback
393 * If set to a valid callback, this will be called every time an error
394 * is pushed onto the stack. The return value will be used to determine
395 * whether to allow an error to be pushed or logged.
397 * The return value must be one of the ERRORSTACK_* constants.
399 * This functionality can be used to emulate PEAR's pushErrorHandling, and
400 * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of
401 * the error stack or logging
402 * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
404 * @param string|array $cb
406 function pushCallback($cb)
408 array_push($this->_errorCallback, $cb);
412 * Remove a callback from the error callback stack
413 * @see pushCallback()
414 * @return array|string|false
416 function popCallback()
418 if (!count($this->_errorCallback)) {
421 return array_pop($this->_errorCallback);
425 * Set a temporary overriding error callback for every package error stack
427 * Use this to temporarily disable all existing callbacks (can be used
428 * to emulate the @ operator, for instance)
429 * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
430 * @see staticPopCallback(), pushCallback()
431 * @param string|array $cb
433 public static function staticPushCallback($cb)
435 array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
439 * Remove a temporary overriding error callback
440 * @see staticPushCallback()
441 * @return array|string|false
443 public static function staticPopCallback()
445 $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
446 if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
447 $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
453 * Add an error to the stack
455 * If the message generator exists, it is called with 2 parameters.
456 * - the current Error Stack object
457 * - an array that is in the same format as an error. Available indices
458 * are 'code', 'package', 'time', 'params', 'level', and 'context'
460 * Next, if the error should contain context information, this is
461 * handled by the context grabbing method.
462 * Finally, the error is pushed onto the proper error stack
463 * @param int $code Package-specific error code
464 * @param string $level Error level. This is NOT spell-checked
465 * @param array $params associative array of error parameters
466 * @param string $msg Error message, or a portion of it if the message
468 * @param array $repackage If this error re-packages an error pushed by
469 * another package, place the array returned from
470 * {@link pop()} in this parameter
471 * @param array $backtrace Protected parameter: use this to pass in the
472 * {@link debug_backtrace()} that should be used
473 * to find error context
474 * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
475 * thrown. If a PEAR_Error is returned, the userinfo
476 * property is set to the following array:
481 * 'params' => $params,
482 * 'package' => $this->_package,
485 * 'context' => $context,
487 * //['repackage' => $err] repackaged error array/Exception class
491 * Normally, the previous array is returned.
493 function push($code, $level = 'error', $params = array(), $msg = false,
494 $repackage = false, $backtrace = false)
497 // grab error context
498 if ($this->_contextCallback) {
500 $backtrace = debug_backtrace();
502 $context = call_user_func($this->_contextCallback, $code, $params, $backtrace);
506 $time = explode(' ', microtime());
507 $time = $time[1] + $time[0];
511 'package' => $this->_package,
514 'context' => $context,
519 $err['repackage'] = $repackage;
522 // set up the error message, if necessary
523 if ($this->_msgCallback) {
524 $msg = call_user_func_array($this->_msgCallback,
525 array(&$this, $err));
526 $err['message'] = $msg;
530 // try the overriding callback first
531 $callback = $this->staticPopCallback();
533 $this->staticPushCallback($callback);
535 if (!is_callable($callback)) {
536 // try the local callback next
537 $callback = $this->popCallback();
538 if (is_callable($callback)) {
539 $this->pushCallback($callback);
541 // try the default callback
542 $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ?
543 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] :
544 $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*'];
547 if (is_callable($callback)) {
548 switch(call_user_func($callback, $err)){
549 case PEAR_ERRORSTACK_IGNORE:
552 case PEAR_ERRORSTACK_PUSH:
555 case PEAR_ERRORSTACK_LOG:
558 case PEAR_ERRORSTACK_DIE:
561 // anything else returned has the same effect as pushandlog
565 array_unshift($this->_errors, $err);
566 if (!isset($this->_errorsByLevel[$err['level']])) {
567 $this->_errorsByLevel[$err['level']] = array();
569 $this->_errorsByLevel[$err['level']][] = &$this->_errors[0];
572 if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) {
579 if ($this->_compat && $push) {
580 return $this->raiseError($msg, $code, null, null, $err);
586 * Static version of {@link push()}
588 * @param string $package Package name this error belongs to
589 * @param int $code Package-specific error code
590 * @param string $level Error level. This is NOT spell-checked
591 * @param array $params associative array of error parameters
592 * @param string $msg Error message, or a portion of it if the message
594 * @param array $repackage If this error re-packages an error pushed by
595 * another package, place the array returned from
596 * {@link pop()} in this parameter
597 * @param array $backtrace Protected parameter: use this to pass in the
598 * {@link debug_backtrace()} that should be used
599 * to find error context
600 * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
601 * thrown. see docs for {@link push()}
603 public static function staticPush(
604 $package, $code, $level = 'error', $params = array(),
605 $msg = false, $repackage = false, $backtrace = false
607 $s = &PEAR_ErrorStack::singleton($package);
608 if ($s->_contextCallback) {
610 if (function_exists('debug_backtrace')) {
611 $backtrace = debug_backtrace();
615 return $s->push($code, $level, $params, $msg, $repackage, $backtrace);
619 * Log an error using PEAR::Log
620 * @param array $err Error array
621 * @param array $levels Error level => Log constant map
626 if ($this->_logger) {
627 $logger = &$this->_logger;
629 $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'];
631 if (is_a($logger, 'Log')) {
633 'exception' => PEAR_LOG_CRIT,
634 'alert' => PEAR_LOG_ALERT,
635 'critical' => PEAR_LOG_CRIT,
636 'error' => PEAR_LOG_ERR,
637 'warning' => PEAR_LOG_WARNING,
638 'notice' => PEAR_LOG_NOTICE,
639 'info' => PEAR_LOG_INFO,
640 'debug' => PEAR_LOG_DEBUG);
641 if (isset($levels[$err['level']])) {
642 $level = $levels[$err['level']];
644 $level = PEAR_LOG_INFO;
646 $logger->log($err['message'], $level, $err);
647 } else { // support non-standard logs
648 call_user_func($logger, $err);
654 * Pop an error off of the error stack
656 * @return false|array
657 * @since 0.4alpha it is no longer possible to specify a specific error
658 * level to return - the last error pushed will be returned, instead
662 $err = @array_shift($this->_errors);
663 if (!is_null($err)) {
664 @array_pop($this->_errorsByLevel[$err['level']]);
665 if (!count($this->_errorsByLevel[$err['level']])) {
666 unset($this->_errorsByLevel[$err['level']]);
673 * Pop an error off of the error stack, static method
675 * @param string package name
679 function staticPop($package)
682 if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
685 return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
690 * Determine whether there are any errors on the stack
691 * @param string|array Level name. Use to determine if any errors
692 * of level (string), or levels (array) have been pushed
695 function hasErrors($level = false)
698 return isset($this->_errorsByLevel[$level]);
700 return count($this->_errors);
704 * Retrieve all errors since last purge
706 * @param boolean set in order to empty the error stack
707 * @param string level name, to return only errors of a particular severity
710 function getErrors($purge = false, $level = false)
714 if (!isset($this->_errorsByLevel[$level])) {
717 return $this->_errorsByLevel[$level];
720 return $this->_errors;
724 $ret = $this->_errorsByLevel[$level];
725 foreach ($this->_errorsByLevel[$level] as $i => $unused) {
726 // entries are references to the $_errors array
727 $this->_errorsByLevel[$level][$i] = false;
729 // array_filter removes all entries === false
730 $this->_errors = array_filter($this->_errors);
731 unset($this->_errorsByLevel[$level]);
734 $ret = $this->_errors;
735 $this->_errors = array();
736 $this->_errorsByLevel = array();
741 * Determine whether there are any errors on a single error stack, or on any error stack
743 * The optional parameter can be used to test the existence of any errors without the need of
744 * singleton instantiation
745 * @param string|false Package name to check for errors
746 * @param string Level name to check for a particular severity
749 public static function staticHasErrors($package = false, $level = false)
752 if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
755 return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level);
757 foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
758 if ($obj->hasErrors($level)) {
766 * Get a list of all errors since last purge, organized by package
767 * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be
768 * @param boolean $purge Set to purge the error stack of existing errors
769 * @param string $level Set to a level name in order to retrieve only errors of a particular level
770 * @param boolean $merge Set to return a flat array, not organized by package
771 * @param array $sortfunc Function used to sort a merged array - default
772 * sorts by time, and should be good for most cases
776 public static function staticGetErrors(
777 $purge = false, $level = false, $merge = false,
778 $sortfunc = array('PEAR_ErrorStack', '_sortErrors')
781 if (!is_callable($sortfunc)) {
782 $sortfunc = array('PEAR_ErrorStack', '_sortErrors');
784 foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
785 $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level);
788 $ret = array_merge($ret, $test);
790 $ret[$package] = $test;
795 usort($ret, $sortfunc);
801 * Error sorting function, sorts by time
804 public static function _sortErrors($a, $b)
806 if ($a['time'] == $b['time']) {
809 if ($a['time'] < $b['time']) {
816 * Standard file/line number/function/class context callback
818 * This function uses a backtrace generated from {@link debug_backtrace()}
819 * and so will not work at all in PHP < 4.3.0. The frame should
820 * reference the frame that contains the source of the error.
821 * @return array|false either array('file' => file, 'line' => line,
822 * 'function' => function name, 'class' => class name) or
823 * if this doesn't work, then false
825 * @param integer backtrace frame.
826 * @param array Results of debug_backtrace()
828 public static function getFileLine($code, $params, $backtrace = null)
830 if ($backtrace === null) {
835 if (!isset($backtrace[1])) {
838 while (isset($backtrace[$functionframe]['function']) &&
839 $backtrace[$functionframe]['function'] == 'eval' &&
840 isset($backtrace[$functionframe + 1])) {
844 if (isset($backtrace[$frame])) {
845 if (!isset($backtrace[$frame]['file'])) {
848 $funcbacktrace = $backtrace[$functionframe];
849 $filebacktrace = $backtrace[$frame];
850 $ret = array('file' => $filebacktrace['file'],
851 'line' => $filebacktrace['line']);
852 // rearrange for eval'd code or create function errors
853 if (strpos($filebacktrace['file'], '(') &&
854 preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
856 $ret['file'] = $matches[1];
857 $ret['line'] = $matches[2] + 0;
859 if (isset($funcbacktrace['function']) && isset($backtrace[1])) {
860 if ($funcbacktrace['function'] != 'eval') {
861 if ($funcbacktrace['function'] == '__lambda_func') {
862 $ret['function'] = 'create_function() code';
864 $ret['function'] = $funcbacktrace['function'];
868 if (isset($funcbacktrace['class']) && isset($backtrace[1])) {
869 $ret['class'] = $funcbacktrace['class'];
877 * Standard error message generation callback
879 * This method may also be called by a custom error message generator
880 * to fill in template values from the params array, simply
881 * set the third parameter to the error message template string to use
883 * The special variable %__msg% is reserved: use it only to specify
884 * where a message passed in by the user should be placed in the template,
887 * Error message: %msg% - internal error
889 * If the message passed like so:
892 * $stack->push(ERROR_CODE, 'error', array(), 'server error 500');
895 * The returned error message will be "Error message: server error 500 -
897 * @param PEAR_ErrorStack
899 * @param string|false Pre-generated error message template
903 public static function getErrorMessage(&$stack, $err, $template = false)
906 $mainmsg = $template;
908 $mainmsg = $stack->getErrorMessageTemplate($err['code']);
910 $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);
911 if (is_array($err['params']) && count($err['params'])) {
912 foreach ($err['params'] as $name => $val) {
913 if (is_array($val)) {
914 // @ is needed in case $val is a multi-dimensional array
915 $val = @implode(', ', $val);
917 if (is_object($val)) {
918 if (method_exists($val, '__toString')) {
919 $val = $val->__toString();
921 PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING,
922 'warning', array('obj' => get_class($val)),
923 'object %obj% passed into getErrorMessage, but has no __toString() method');
927 $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
934 * Standard Error Message Template generator from code
937 function getErrorMessageTemplate($code)
939 if (!isset($this->_errorMsgs[$code])) {
942 return $this->_errorMsgs[$code];
946 * Set the Error Message Template array
948 * The array format must be:
950 * array(error code => 'message template',...)
953 * Error message parameters passed into {@link push()} will be used as input
954 * for the error message. If the template is 'message %foo% was %bar%', and the
955 * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will
956 * be 'message one was six'
959 function setErrorMessageTemplate($template)
961 $this->_errorMsgs = $template;
966 * emulate PEAR::raiseError()
970 function raiseError()
972 require_once 'PEAR.php';
973 $args = func_get_args();
974 return call_user_func_array(array('PEAR', 'raiseError'), $args);
977 $stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack');
978 $stack->pushCallback(array('PEAR_ErrorStack', '_handleError'));