Joomla Platform  13.1
Documentation des API du framework Joomla Platform
 Tout Classes Espaces de nommage Fichiers Fonctions Variables Pages
error.php
Aller à la documentation de ce fichier.
1 <?php
2 /**
3  * @package Joomla.Legacy
4  * @subpackage Error
5  *
6  * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
7  * @license GNU General Public License version 2 or later; see LICENSE
8  */
9 
10 defined('JPATH_PLATFORM') or die;
11 
12 // Error Definition: Illegal Options
14 
15 // Error Definition: Callback does not exist
17 
18 // Error Definition: Illegal Handler
20 
21 /**
22  * Error Handling Class
23  *
24  * This class is inspired in design and concept by patErrorManager <http://www.php-tools.net>
25  *
26  * patErrorManager contributors include:
27  * - gERD Schaufelberger <gerd@php-tools.net>
28  * - Sebastian Mordziol <argh@php-tools.net>
29  * - Stephan Schmidt <scst@php-tools.net>
30  *
31  * @package Joomla.Legacy
32  * @subpackage Error
33  * @since 11.1
34  * @deprecated 12.1 (Platform) & 4.0 (CMS) - Use PHP Exception
35  */
36 abstract class JError
37 {
38  /**
39  * Legacy error handling marker
40  *
41  * @var boolean True to enable legacy error handling using JError, false to use exception handling. This flag
42  * is present to allow an easy transition into exception handling for code written against the
43  * existing JError API in Joomla.
44  * @since 11.1
45  */
46  public static $legacy = false;
47 
48  /**
49  * Array of message levels
50  *
51  * @var array
52  * @since 11.1
53  */
54  protected static $levels = array(E_NOTICE => 'Notice', E_WARNING => 'Warning', E_ERROR => 'Error');
55 
56  /**
57  * Array of message handlers
58  * @var array
59  * @since 11.1
60  */
61  protected static $handlers = array(
62  E_NOTICE => array('mode' => 'ignore'),
63  E_WARNING => array('mode' => 'ignore'),
64  E_ERROR => array('mode' => 'ignore')
65  );
66 
67  /**
68  * Array containing the error stack
69  *
70  * @var array
71  * @since 11.1
72  */
73  protected static $stack = array();
74 
75  /**
76  * Method to determine if a value is an exception object.
77  *
78  * @param mixed $object Object to check.
79  *
80  * @return boolean True if argument is an exception, false otherwise.
81  *
82  * @deprecated 12.1
83  * @since 11.1
84  */
85  public static function isError($object)
86  {
87  JLog::add('JError::isError() is deprecated.', JLog::WARNING, 'deprecated');
88 
89  return $object instanceof Exception;
90  }
91 
92  /**
93  * Method for retrieving the last exception object in the error stack
94  *
95  * @param boolean $unset True to remove the error from the stack.
96  *
97  * @return mixed Last exception object in the error stack or boolean false if none exist
98  *
99  * @deprecated 12.1
100  * @since 11.1
101  */
102  public static function getError($unset = false)
103  {
104  JLog::add('JError::getError() is deprecated.', JLog::WARNING, 'deprecated');
105 
106  if (!isset(self::$stack[0]))
107  {
108  return false;
109  }
110 
111  if ($unset)
112  {
113  $error = array_shift(self::$stack);
114  }
115  else
116  {
117  $error = &self::$stack[0];
118  }
119  return $error;
120  }
121 
122  /**
123  * Method for retrieving the exception stack
124  *
125  * @return array Chronological array of errors that have been stored during script execution
126  *
127  * @deprecated 12.1
128  * @since 11.1
129  */
130  public static function getErrors()
131  {
132  JLog::add('JError::getErrors() is deprecated.', JLog::WARNING, 'deprecated');
133 
134  return self::$stack;
135  }
136 
137  /**
138  * Method to add non-JError thrown JExceptions to the JError stack for debugging purposes
139  *
140  * @param JException &$e Add an exception to the stack.
141  *
142  * @return void
143  *
144  * @since 11.1
145  * @deprecated 12.1
146  */
147  public static function addToStack(JException &$e)
148  {
149  JLog::add('JError::addToStack() is deprecated.', JLog::WARNING, 'deprecated');
150 
151  self::$stack[] = &$e;
152  }
153 
154  /**
155  * Create a new JException object given the passed arguments
156  *
157  * @param integer $level The error level - use any of PHP's own error levels for
158  * this: E_ERROR, E_WARNING, E_NOTICE, E_USER_ERROR,
159  * E_USER_WARNING, E_USER_NOTICE.
160  * @param string $code The application-internal error code for this error
161  * @param string $msg The error message, which may also be shown the user if need be.
162  * @param mixed $info Optional: Additional error information (usually only
163  * developer-relevant information that the user should never see,
164  * like a database DSN).
165  * @param boolean $backtrace Add a stack backtrace to the exception.
166  *
167  * @return mixed The JException object
168  *
169  * @since 11.1
170  * @deprecated 12.1 Use PHP Exception
171  * @see JException
172  */
173  public static function raise($level, $code, $msg, $info = null, $backtrace = false)
174  {
175  JLog::add('JError::raise() is deprecated.', JLog::WARNING, 'deprecated');
176 
177  // Build error object
178  $exception = new JException($msg, $code, $level, $info, $backtrace);
179  return self::throwError($exception);
180  }
181 
182  /**
183  * Throw an error
184  *
185  * @param object &$exception An exception to throw.
186  *
187  * @return reference
188  *
189  * @deprecated 12.1 Use PHP Exception
190  * @see JException
191  * @since 11.1
192  */
193  public static function throwError(&$exception)
194  {
195  JLog::add('JError::throwError() is deprecated.', JLog::WARNING, 'deprecated');
196 
197  static $thrown = false;
198 
199  // If thrown is hit again, we've come back to JError in the middle of throwing another JError, so die!
200  if ($thrown)
201  {
202  self::handleEcho($exception, array());
203 
204  // Inifite loop.
205  jexit();
206  }
207 
208  $thrown = true;
209  $level = $exception->get('level');
210 
211  // See what to do with this kind of error
212  $handler = self::getErrorHandling($level);
213 
214  $function = 'handle' . ucfirst($handler['mode']);
215  if (is_callable(array('JError', $function)))
216  {
217  $reference = call_user_func_array(array('JError', $function), array(&$exception, (isset($handler['options'])) ? $handler['options'] : array()));
218  }
219  else
220  {
221  // This is required to prevent a very unhelpful white-screen-of-death
222  jexit(
223  'JError::raise -> Static method JError::' . $function . ' does not exist. Contact a developer to debug' .
224  '<br /><strong>Error was</strong> <br />' . $exception->getMessage()
225  );
226  }
227  // We don't need to store the error, since JException already does that for us!
228  // Remove loop check
229  $thrown = false;
230 
231  return $reference;
232  }
233 
234  /**
235  * Wrapper method for the raise() method with predefined error level of E_ERROR and backtrace set to true.
236  *
237  * @param string $code The application-internal error code for this error
238  * @param string $msg The error message, which may also be shown the user if need be.
239  * @param mixed $info Optional: Additional error information (usually only
240  * developer-relevant information that the user should
241  * never see, like a database DSN).
242  *
243  * @return object $error The configured JError object
244  *
245  * @deprecated 12.1 Use PHP Exception
246  * @see JError::raise()
247  * @since 11.1
248  */
249  public static function raiseError($code, $msg, $info = null)
250  {
251  JLog::add('JError::raiseError() is deprecated.', JLog::WARNING, 'deprecated');
252 
253  return self::raise(E_ERROR, $code, $msg, $info, true);
254  }
255 
256  /**
257  * Wrapper method for the {@link raise()} method with predefined error level of E_WARNING and
258  * backtrace set to false.
259  *
260  * @param string $code The application-internal error code for this error
261  * @param string $msg The error message, which may also be shown the user if need be.
262  * @param mixed $info Optional: Additional error information (usually only
263  * developer-relevant information that
264  * the user should never see, like a database DSN).
265  *
266  * @return object The configured JError object
267  *
268  * @deprecated 12.1 Use PHP Exception
269  * @see JError::raise()
270  * @since 11.1
271  */
272  public static function raiseWarning($code, $msg, $info = null)
273  {
274  JLog::add('JError::raiseWarning() is deprecated.', JLog::WARNING, 'deprecated');
275 
276  return self::raise(E_WARNING, $code, $msg, $info);
277  }
278 
279  /**
280  * Wrapper method for the {@link raise()} method with predefined error
281  * level of E_NOTICE and backtrace set to false.
282  *
283  * @param string $code The application-internal error code for this error
284  * @param string $msg The error message, which may also be shown the user if need be.
285  * @param mixed $info Optional: Additional error information (usually only
286  * developer-relevant information that the user
287  * should never see, like a database DSN).
288  *
289  * @return object The configured JError object
290  *
291  * @deprecated 12.1 Use PHP Exception
292  * @see raise()
293  * @since 11.1
294  */
295  public static function raiseNotice($code, $msg, $info = null)
296  {
297  JLog::add('JError::raiseNotice() is deprecated.', JLog::WARNING, 'deprecated');
298 
299  return self::raise(E_NOTICE, $code, $msg, $info);
300  }
301 
302  /**
303  * Method to get the current error handler settings for a specified error level.
304  *
305  * @param integer $level The error level to retrieve. This can be any of PHP's
306  * own error levels, e.g. E_ALL, E_NOTICE...
307  *
308  * @return array All error handling details
309  *
310  * @deprecated 12.1 Use PHP Exception
311  * @since 11.1
312  */
313  public static function getErrorHandling($level)
314  {
315  JLog::add('JError::getErrorHandling() is deprecated.', JLog::WARNING, 'deprecated');
316 
317  return self::$handlers[$level];
318  }
319 
320  /**
321  * Method to set the way the JError will handle different error levels. Use this if you want to override the default settings.
322  *
323  * Error handling modes:
324  * - ignore
325  * - echo
326  * - verbose
327  * - die
328  * - message
329  * - log
330  * - callback
331  *
332  * You may also set the error handling for several modes at once using PHP's bit operations.
333  * Examples:
334  * - E_ALL = Set the handling for all levels
335  * - E_ERROR | E_WARNING = Set the handling for errors and warnings
336  * - E_ALL ^ E_ERROR = Set the handling for all levels except errors
337  *
338  * @param integer $level The error level for which to set the error handling
339  * @param string $mode The mode to use for the error handling.
340  * @param mixed $options Optional: Any options needed for the given mode.
341  *
342  * @return mixed True on success or a JException object if failed.
343  *
344  * @deprecated 12.1 Use PHP Exception
345  * @since 11.1
346  */
347  public static function setErrorHandling($level, $mode, $options = null)
348  {
349  JLog::add('JError::setErrorHandling() is deprecated.', JLog::WARNING, 'deprecated');
350 
351  $levels = self::$levels;
352 
353  $function = 'handle' . ucfirst($mode);
354 
355  if (!is_callable(array('JError', $function)))
356  {
357  return self::raiseError(E_ERROR, 'JError:' . JERROR_ILLEGAL_MODE, 'Error Handling mode is not known', 'Mode: ' . $mode . ' is not implemented.');
358  }
359 
360  foreach ($levels as $eLevel => $eTitle)
361  {
362  if (($level & $eLevel) != $eLevel)
363  {
364  continue;
365  }
366 
367  // Set callback options
368  if ($mode == 'callback')
369  {
370  if (!is_array($options))
371  {
372  return self::raiseError(E_ERROR, 'JError:' . JERROR_ILLEGAL_OPTIONS, 'Options for callback not valid');
373  }
374 
375  if (!is_callable($options))
376  {
377  $tmp = array('GLOBAL');
378  if (is_array($options))
379  {
380  $tmp[0] = $options[0];
381  $tmp[1] = $options[1];
382  }
383  else
384  {
385  $tmp[1] = $options;
386  }
387 
388  return self::raiseError(
389  E_ERROR,
390  'JError:' . JERROR_CALLBACK_NOT_CALLABLE,
391  'Function is not callable',
392  'Function:' . $tmp[1] . ' scope ' . $tmp[0] . '.'
393  );
394  }
395  }
396 
397  // Save settings
398  self::$handlers[$eLevel] = array('mode' => $mode);
399  if ($options != null)
400  {
401  self::$handlers[$eLevel]['options'] = $options;
402  }
403  }
404 
405  return true;
406  }
407 
408  /**
409  * Method that attaches the error handler to JError
410  *
411  * @return void
412  *
413  * @deprecated 12.1
414  * @see set_error_handler
415  * @since 11.1
416  */
417  public static function attachHandler()
418  {
419  JLog::add('JError::getErrorHandling() is deprecated.', JLog::WARNING, 'deprecated');
420 
421  set_error_handler(array('JError', 'customErrorHandler'));
422  }
423 
424  /**
425  * Method that detaches the error handler from JError
426  *
427  * @return void
428  *
429  * @deprecated 12.1
430  * @see restore_error_handler
431  * @since 11.1
432  */
433  public static function detachHandler()
434  {
435  JLog::add('JError::detachHandler() is deprecated.', JLog::WARNING, 'deprecated');
436 
437  restore_error_handler();
438  }
439 
440  /**
441  * Method to register a new error level for handling errors
442  *
443  * This allows you to add custom error levels to the built-in
444  * - E_NOTICE
445  * - E_WARNING
446  * - E_NOTICE
447  *
448  * @param integer $level Error level to register
449  * @param string $name Human readable name for the error level
450  * @param string $handler Error handler to set for the new error level [optional]
451  *
452  * @return boolean True on success; false if the level already has been registered
453  *
454  * @deprecated 12.1
455  * @since 11.1
456  */
457  public static function registerErrorLevel($level, $name, $handler = 'ignore')
458  {
459  JLog::add('JError::registerErrorLevel() is deprecated.', JLog::WARNING, 'deprecated');
460 
461  if (isset(self::$levels[$level]))
462  {
463  return false;
464  }
465 
466  self::$levels[$level] = $name;
467  self::setErrorHandling($level, $handler);
468 
469  return true;
470  }
471 
472  /**
473  * Translate an error level integer to a human readable string
474  * e.g. E_ERROR will be translated to 'Error'
475  *
476  * @param integer $level Error level to translate
477  *
478  * @return mixed Human readable error level name or boolean false if it doesn't exist
479  *
480  * @deprecated 12.1
481  * @since 11.1
482  */
483 
484  public static function translateErrorLevel($level)
485  {
486  JLog::add('JError::translateErrorLevel() is deprecated.', JLog::WARNING, 'deprecated');
487 
488  if (isset(self::$levels[$level]))
489  {
490  return self::$levels[$level];
491  }
492 
493  return false;
494  }
495 
496  /**
497  * Ignore error handler
498  * - Ignores the error
499  *
500  * @param object &$error Exception object to handle
501  * @param array $options Handler options
502  *
503  * @return object The exception object
504  *
505  * @deprecated 12.1
506  * @see JError::raise()
507  * @since 11.1
508  */
509  public static function handleIgnore(&$error, $options)
510  {
511  JLog::add('JError::handleIgnore() is deprecated.', JLog::WARNING, 'deprecated');
512 
513  return $error;
514  }
515 
516  /**
517  * Echo error handler
518  * - Echos the error message to output
519  *
520  * @param object &$error Exception object to handle
521  * @param array $options Handler options
522  *
523  * @return object The exception object
524  *
525  * @deprecated 12.1
526  * @see JError::raise()
527  * @since 11.1
528  */
529  public static function handleEcho(&$error, $options)
530  {
531  JLog::add('JError::handleEcho() is deprecated.', JLog::WARNING, 'deprecated');
532 
533  $level_human = self::translateErrorLevel($error->get('level'));
534 
535  // If system debug is set, then output some more information.
536  if (defined('JDEBUG'))
537  {
538  $backtrace = $error->getTrace();
539  $trace = '';
540  for ($i = count($backtrace) - 1; $i >= 0; $i--)
541  {
542  if (isset($backtrace[$i]['class']))
543  {
544  $trace .= sprintf("\n%s %s %s()", $backtrace[$i]['class'], $backtrace[$i]['type'], $backtrace[$i]['function']);
545  }
546  else
547  {
548  $trace .= sprintf("\n%s()", $backtrace[$i]['function']);
549  }
550 
551  if (isset($backtrace[$i]['file']))
552  {
553  $trace .= sprintf(' @ %s:%d', $backtrace[$i]['file'], $backtrace[$i]['line']);
554  }
555  }
556  }
557 
558  if (isset($_SERVER['HTTP_HOST']))
559  {
560  // Output as html
561  echo "<br /><b>jos-$level_human</b>: "
562  . $error->get('message') . "<br />\n"
563  . (defined('JDEBUG') ? nl2br($trace) : '');
564  }
565  else
566  {
567  // Output as simple text
568  if (defined('STDERR'))
569  {
570  fwrite(STDERR, "J$level_human: " . $error->get('message') . "\n");
571  if (defined('JDEBUG'))
572  {
573  fwrite(STDERR, $trace);
574  }
575  }
576  else
577  {
578  echo "J$level_human: " . $error->get('message') . "\n";
579  if (defined('JDEBUG'))
580  {
581  echo $trace;
582  }
583  }
584  }
585 
586  return $error;
587  }
588 
589  /**
590  * Verbose error handler
591  * - Echos the error message to output as well as related info
592  *
593  * @param object &$error Exception object to handle
594  * @param array $options Handler options
595  *
596  * @return object The exception object
597  *
598  * @deprecated 12.1
599  * @see JError::raise()
600  * @since 11.1
601  */
602  public static function handleVerbose(&$error, $options)
603  {
604  JLog::add('JError::handleVerbose() is deprecated.', JLog::WARNING, 'deprecated');
605 
606  $level_human = self::translateErrorLevel($error->get('level'));
607  $info = $error->get('info');
608 
609  if (isset($_SERVER['HTTP_HOST']))
610  {
611  // Output as html
612  echo "<br /><b>J$level_human</b>: " . $error->get('message') . "<br />\n";
613 
614  if ($info != null)
615  {
616  echo "&#160;&#160;&#160;" . $info . "<br />\n";
617  }
618 
619  echo $error->getBacktrace(true);
620  }
621  else
622  {
623  // Output as simple text
624  echo "J$level_human: " . $error->get('message') . "\n";
625  if ($info != null)
626  {
627  echo "\t" . $info . "\n";
628  }
629 
630  }
631 
632  return $error;
633  }
634 
635  /**
636  * Die error handler
637  * - Echos the error message to output and then dies
638  *
639  * @param object &$error Exception object to handle
640  * @param array $options Handler options
641  *
642  * @return object The exception object
643  *
644  * @deprecated 12.1
645  * @see JError::raise()
646  * @since 11.1
647  */
648  public static function handleDie(&$error, $options)
649  {
650  JLog::add('JError::handleDie() is deprecated.', JLog::WARNING, 'deprecated');
651 
652  $level_human = self::translateErrorLevel($error->get('level'));
653 
654  if (isset($_SERVER['HTTP_HOST']))
655  {
656  // Output as html
657  jexit("<br /><b>J$level_human</b>: " . $error->get('message') . "<br />\n");
658  }
659  else
660  {
661  // Output as simple text
662  if (defined('STDERR'))
663  {
664  fwrite(STDERR, "J$level_human: " . $error->get('message') . "\n");
665  jexit();
666  }
667  else
668  {
669  jexit("J$level_human: " . $error->get('message') . "\n");
670  }
671  }
672 
673  return $error;
674  }
675 
676  /**
677  * Message error handler
678  * Enqueues the error message into the system queue
679  *
680  * @param object &$error Exception object to handle
681  * @param array $options Handler options
682  *
683  * @return object The exception object
684  *
685  * @deprecated 12.1
686  * @see JError::raise()
687  * @since 11.1
688  */
689  public static function handleMessage(&$error, $options)
690  {
691  JLog::add('JError::hanleMessage() is deprecated.', JLog::WARNING, 'deprecated');
692 
693  $appl = JFactory::getApplication();
694  $type = ($error->get('level') == E_NOTICE) ? 'notice' : 'error';
695  $appl->enqueueMessage($error->get('message'), $type);
696 
697  return $error;
698  }
699 
700  /**
701  * Log error handler
702  * Logs the error message to a system log file
703  *
704  * @param object &$error Exception object to handle
705  * @param array $options Handler options
706  *
707  * @return object The exception object
708  *
709  * @deprecated 12.1
710  * @see JError::raise()
711  * @since 11.1
712  */
713  public static function handleLog(&$error, $options)
714  {
715  JLog::add('JError::handleLog() is deprecated.', JLog::WARNING, 'deprecated');
716 
717  static $log;
718 
719  if ($log == null)
720  {
721  $options['text_file'] = date('Y-m-d') . '.error.log';
722  $options['format'] = "{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}";
723  JLog::addLogger($options, JLog::ALL, array('error'));
724  }
725 
726  $entry = new JLogEntry(
727  str_replace(array("\r", "\n"), array('', '\\n'), $error->get('message')),
728  $error->get('level'),
729  'error'
730  );
731  $entry->code = $error->get('code');
732  JLog::add($entry);
733 
734  return $error;
735  }
736 
737  /**
738  * Callback error handler
739  * - Send the error object to a callback method for error handling
740  *
741  * @param object &$error Exception object to handle
742  * @param array $options Handler options
743  *
744  * @return object The exception object
745  *
746  * @deprecated 12.1
747  * @see JError::raise()
748  * @since 11.1
749  */
750  public static function handleCallback(&$error, $options)
751  {
752  JLog::add('JError::handleCallback() is deprecated.', JLog::WARNING, 'deprecated');
753 
754  return call_user_func($options, $error);
755  }
756 
757  /**
758  * Display a custom error page and exit gracefully
759  *
760  * @param object &$error Exception object
761  *
762  * @return void
763  *
764  * @deprecated 12.1
765  * @since 11.1
766  */
767  public static function customErrorPage(&$error)
768  {
769  JLog::add('JError::customErrorPage() is deprecated.', JLog::WARNING, 'deprecated');
770 
771  $app = JFactory::getApplication();
772  $document = JDocument::getInstance('error');
773  if ($document)
774  {
775  $config = JFactory::getConfig();
776 
777  // Get the current template from the application
778  $template = $app->getTemplate();
779 
780  // Push the error object into the document
781  $document->setError($error);
782 
783  // If site is offline and it's a 404 error, just go to index (to see offline message, instead of 404)
784  if ($error->getCode() == '404' && JFactory::getConfig()->get('offline') == 1)
785  {
786  JFactory::getApplication()->redirect('index.php');
787  }
788 
789  @ob_end_clean();
790  $document->setTitle(JText::_('Error') . ': ' . $error->getCode());
791  $data = $document->render(false, array('template' => $template, 'directory' => JPATH_THEMES, 'debug' => $config->get('debug')));
792 
793  // Failsafe to get the error displayed.
794  if (empty($data))
795  {
796  self::handleEcho($error, array());
797  }
798  else
799  {
800  // Do not allow cache
801  $app->allowCache(false);
802 
803  $app->setBody($data);
804  echo $app->toString();
805  }
806  }
807  else
808  {
809  // Just echo the error since there is no document
810  // This is a common use case for Command Line Interface applications.
811  self::handleEcho($error, array());
812  }
813  $app->close(0);
814  }
815 
816  /**
817  * Display a message to the user
818  *
819  * @param integer $level The error level - use any of PHP's own error levels
820  * for this: E_ERROR, E_WARNING, E_NOTICE, E_USER_ERROR,
821  * E_USER_WARNING, E_USER_NOTICE.
822  * @param string $msg Error message, shown to user if need be.
823  *
824  * @return void
825  *
826  * @deprecated 12.1
827  * @since 11.1
828  */
829  public static function customErrorHandler($level, $msg)
830  {
831  JLog::add('JError::customErrorHandler() is deprecated.', JLog::WARNING, 'deprecated');
832 
833  self::raise($level, '', $msg);
834  }
835 
836  /**
837  * Render the backtrace
838  *
839  * @param integer $error The error
840  *
841  * @return string Contents of the backtrace
842  *
843  * @deprecated 12.1
844  * @since 11.1
845  */
846  public static function renderBacktrace($error)
847  {
848  JLog::add('JError::renderBacktrace() is deprecated.', JLog::WARNING, 'deprecated');
849 
850  $contents = null;
851  $backtrace = $error->getTrace();
852 
853  if (is_array($backtrace))
854  {
855  ob_start();
856  $j = 1;
857  echo '<table cellpadding="0" cellspacing="0" class="Table">';
858  echo ' <tr>';
859  echo ' <td colspan="3" class="TD"><strong>Call stack</strong></td>';
860  echo ' </tr>';
861  echo ' <tr>';
862  echo ' <td class="TD"><strong>#</strong></td>';
863  echo ' <td class="TD"><strong>Function</strong></td>';
864  echo ' <td class="TD"><strong>Location</strong></td>';
865  echo ' </tr>';
866 
867  for ($i = count($backtrace) - 1; $i >= 0; $i--)
868  {
869  echo ' <tr>';
870  echo ' <td class="TD">' . $j . '</td>';
871 
872  if (isset($backtrace[$i]['class']))
873  {
874  echo ' <td class="TD">' . $backtrace[$i]['class'] . $backtrace[$i]['type'] . $backtrace[$i]['function'] . '()</td>';
875  }
876  else
877  {
878  echo ' <td class="TD">' . $backtrace[$i]['function'] . '()</td>';
879  }
880 
881  if (isset($backtrace[$i]['file']))
882  {
883  echo ' <td class="TD">' . $backtrace[$i]['file'] . ':' . $backtrace[$i]['line'] . '</td>';
884  }
885  else
886  {
887  echo ' <td class="TD">&#160;</td>';
888  }
889 
890  echo ' </tr>';
891  $j++;
892  }
893 
894  echo '</table>';
895  $contents = ob_get_contents();
896  ob_end_clean();
897  }
898 
899  return $contents;
900  }
901 }