ErrorHandler.php

Go to the documentation of this file.
00001 <?php
00003 // {{{ license
00004 
00005 // +----------------------------------------------------------------------+
00006 // | FastFrame Application Framework                                      |
00007 // +----------------------------------------------------------------------+
00008 // | Copyright (c) 2002-2006 The Codejanitor Group                        |
00009 // +----------------------------------------------------------------------+
00010 // | This source file is subject to the GNU Lesser Public License (LGPL), |
00011 // | that is bundled with this package in the file LICENSE, and is        |
00012 // | available at through the world-wide-web at                           |
00013 // | http://www.fsf.org/copyleft/lesser.html                              |
00014 // | If you did not receive a copy of the LGPL and are unable to          |
00015 // | obtain it through the world-wide-web, you can get it by writing the  |
00016 // | Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
00017 // | MA 02111-1307, USA.                                                  |
00018 // +----------------------------------------------------------------------+
00019 // | Authors: Jason Rust <jrust@codejanitor.com>                          |
00020 // |          Dan Allen <dan@mojavelinux.com>                             |
00021 // +----------------------------------------------------------------------+
00022 
00023 // }}}
00024 // {{{ constants
00025 
00026 define('E_USER_ALL', E_USER_NOTICE | E_USER_WARNING | E_USER_ERROR);
00027 define('E_NOTICE_ALL', E_NOTICE | E_USER_NOTICE);
00028 define('E_WARNING_ALL', E_WARNING | E_USER_WARNING | E_CORE_WARNING | E_COMPILE_WARNING);
00029 define('E_ERROR_ALL', E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR);
00030 define('E_NOTICE_NONE', E_ALL & ~E_NOTICE_ALL);
00031 define('E_DEBUG', 0x10000000);
00032 define('E_VERY_ALL', E_ERROR_ALL | E_WARNING_ALL | E_NOTICE_ALL | E_DEBUG);
00033 
00034 define('SYSTEM_LOG', 0);
00035 define('TCP_LOG',    2);
00036 define('MAIL_LOG',   1);
00037 define('FILE_LOG',   3);
00038 
00039 // }}}
00040 // {{{ class FF_ErrorHandler
00041 
00055 // }}}
00056 class FF_ErrorHandler {
00057     // {{{ properties
00058 
00063     var $errorList = array();
00064 
00069     var $consoleErrors = array();
00070 
00075     var $mailErrors = array();
00076 
00081     var $reporters = array(
00082             'mail'      => array('level' => 0, 'data' => null),
00083             'file'      => array('level' => 0, 'data' => null),
00084             'console'   => array('level' => 0, 'data' => null),
00085             'stdout'    => array('level' => 0, 'data' => null),
00086             'system'    => array('level' => 0, 'data' => null),
00087             'redirect'  => array('level' => 0, 'data' => null),
00088             'browser'   => array('level' => 0, 'data' => null));
00089   
00094     var $fileUrl = '';
00095 
00100     var $contextLines = 5;
00101 
00107     var $strictContext = true;
00108 
00113     var $dateFormat = '[Y-m-d H:i:s]';
00114 
00119     var $classExcludeList = array();
00120 
00125     var $excludeObjects = true;
00126 
00131     var $templates = array(
00132             'message' => '<b>%date%</b> <span class="errorLevel">[%errorLevel%]</span> in %file% on line <span style="text-decoration: underline; padding-bottom: 1px; border-bottom: 1px solid black;">%line%</span>
00133 <div class="errorMessage">%errorMessage%</div>',
00134             'header' => '<div id="%id%" style="border: thin solid #000; background-color: #eee; margin: 5px 5px 2px 5px; font-weight: bold;">==> %header%</div>',
00135             'variable' => '<div style="margin: 0px 5px 5px 5px;">%variable%</div>',
00136             'backtrace' => '<div style="margin: 0px 5px 5px 5px;"><b>%num%</b>. Function %func% called in %file% on line %line%</div>',
00137             'sourceMessage' => 'Source report from %file% around line %line% (%ctxStart% - %ctxEnd%)',
00138             'source' => '<div style="margin: 0 5px 5px 5px; background-color: #eee; border: 1px dashed #000;">%source%</div>');
00139 
00144     var $_signatures = array();
00145 
00146     // }}}
00147     // {{{ __constructor()
00148 
00156     function FF_ErrorHandler($in_reporters)
00157     {
00158         // Determine the levels we will be reporting
00159         $s_errorLevel = 0;
00160         foreach ($in_reporters as $s_type => $a_reporter) {
00161             // AJAX requests shouldn't get html errors
00162             if (IS_AJAX && ($s_type == 'console' || $s_type == 'browser')) {
00163                 $s_type = 'stdout';
00164             }
00165 
00166             $a_reporter['data'] = isset($a_reporter['data']) ? $a_reporter['data'] : null;
00167             $s_errorLevel |= $a_reporter['level'];
00168             $this->_addReporter($s_type, $a_reporter['level'], $a_reporter['data']);
00169         }
00170 
00171         error_reporting($s_errorLevel);
00172         // No point having errors passed to us that we aren't catching, hence $s_errorLevel
00173         if (version_compare(phpversion(), '5.0') === -1) {
00174             // PHP4 doesn't take the 2nd arg, and until 4.3 it doesn't support caling a method with an array
00175             set_error_handler('php4_errorHandler');
00176             register_shutdown_function('php4_errorHandler');
00177         }
00178         else {
00179             set_error_handler(array(&$this, '_trapError'), $s_errorLevel);
00180             register_shutdown_function(array(&$this, '__destructor'));
00181         }
00182     }
00183     
00184     // }}}
00185     // {{{ __destructor()
00186 
00187     function __destructor()
00188     {
00189         error_reporting(E_ALL ^ E_NOTICE);
00190         // Process errors
00191         foreach ($this->errorList as $a_error) {
00192             $this->_processError($a_error);
00193         }
00194 
00195         // Handle those reporters that handle their errors as a batch
00196         if (count($this->consoleErrors)) {
00197             $a_errors =& $this->consoleErrors;
00198             include dirname(__FILE__) . '/ErrorHandler/error.tpl.php';
00199         }
00200 
00201         if (count($this->mailErrors)) {
00202             $msg = _('User Information:') . "\n";
00203             $msg .= "\t" . _('Username') . ': ' . FF_Auth::getCredential('username') . "\n"; 
00204             $msg .= "\tSERVER_NAME: " . $_SERVER['SERVER_NAME'] . "\n";
00205             $msg .= "\tREQUEST_URI: " . $_SERVER['REQUEST_URI'] . "\n";
00206             $msg .= "\tHTTP_REFERER: " . $_SERVER['HTTP_REFERER'] . "\n";
00207             $msg .= "\tHTTP_USER_AGENT: " . $_SERVER['HTTP_USER_AGENT'] . "\n\n";
00208             $msg .= implode(str_repeat('-=', 50) . "\n\n", $this->mailErrors);
00209             @error_log($this->_cleanMessage($msg), MAIL_LOG, $this->reporters['mail']['data']);
00210         }
00211     }
00212 
00213     // }}}
00214     // {{{ setTemplate()
00215 
00226     function setTemplate($in_name, $in_template)
00227     {
00228         $this->templates[$in_name] = $in_template;
00229     }
00230 
00231     // }}}
00232     // {{{ setFileUrl()
00233 
00243     function setFileUrl($in_value)
00244     {
00245         $this->fileUrl = $in_value;
00246     }
00247 
00248     // }}}
00249     // {{{ setDateFormat()
00250 
00251     function setDateFormat($in_format)
00252     {
00253         $this->dateFormat = $in_format;
00254     }
00255 
00256     // }}}
00257     // {{{ setContextLines()
00258 
00259     function setContextLines($in_lines)
00260     {
00261         $this->contextLines = intval($lines);
00262     }
00263 
00264     // }}}
00265     // {{{ setStrictContext()
00266 
00267     function setStrictContext($bool)
00268     {
00269         $this->strictContext = $bool ? true : false;
00270     }
00271 
00272     // }}}
00273     // {{{ setExcludeObjects()
00274 
00283     function setExcludeObjects()
00284     {
00285         if (gettype(func_get_arg(0)) == 'boolean') {
00286             $this->excludeObjects = func_get_arg(0);
00287         }
00288         else {
00289             $list = func_get_args();
00290             $this->classExcludeList = array_map('strtolower', $list);
00291         }
00292     }
00293 
00294     // }}}
00295     // {{{ addError()
00296 
00305     function addError($in_error)
00306     {
00307         // rearrange for eval'd code or create function errors
00308         if (preg_match(';^(.*?)\((\d+)\) : (.*?)$;', $in_error['file'], $matches)) {
00309             $in_error['message'] .= ' on line ' . $in_error['line'] . ' in ' . $matches[3];
00310             $in_error['file'] = $matches[1];
00311             $in_error['line'] = $matches[2];
00312         }
00313 
00314         $in_error['date'] = date($this->dateFormat);
00315         $in_error['context'] = $this->_getContext($in_error['file'], $in_error['line']);
00316         if (function_exists('debug_backtrace')) {
00317             $in_error['backtrace'] = debug_backtrace();
00318         }
00319         else {
00320             $in_error['backtrace'] = array();
00321         }
00322 
00323         $this->errorList[] = $in_error;
00324         // E_USER_ERROR are showstoppers
00325         if ($in_error['level'] == E_USER_ERROR) {
00326             $this->_fatal($in_error);
00327         }
00328     }
00329 
00330     // }}}
00331     // {{{ debug()
00332 
00345     function debug($in_variable, $in_name = '*variable*', $in_line = '*line*', $in_file = '*file*', $in_level = E_DEBUG)
00346     {
00347         $a_error = array('level' => intval($in_level), 
00348                 'message' => 'user variable debug: $' . $in_name,
00349                 'file' => $in_file, 'line' => $in_line,
00350                 'variables' => array($in_name => $in_variable), 'signature' => mt_rand());
00351         $this->addError($a_error);
00352     }
00353 
00354     // }}}
00355     // {{{ _trapError()
00356 
00357     function _trapError($in_errno, $in_errstr, $in_errfile, $in_errline, $in_errcontext)
00358     {
00359         // silenced error (using @)
00360         if (error_reporting() == 0) {
00361             return;
00362         }
00363         
00364         // Weed out duplicate errors (coming from same line and file)
00365         $signature = md5($in_errstr . ':' . $in_errfile . ':' . $in_errline);
00366         if (isset($this->signatures[$signature])) {
00367             return;
00368         }
00369         else {
00370             $this->signatures[$signature] = true;
00371         }
00372 
00373         // Cut out the fat from the variable context (we get back a lot of junk)
00374         $variables =& $in_errcontext;
00375         $variablesFiltered = array();
00376         foreach (array_keys($variables) as $variableName) {
00377             // These are server variables most likely
00378             if ($variableName == strtoupper($variableName) ||
00379                 // Private/Super-Global vars
00380                 $variableName{0} == '_' ||
00381                 // Passed in vars
00382                 $variableName == 'argv' || $variableName == 'argc' ||
00383                 // See if objects should be excluded
00384                 ($this->excludeObjects && gettype($variables[$variableName]) == 'object') ||
00385                 // Don't allow instance of errorstack to come through
00386                 is_a($variables[$variableName], 'FF_ErrorHandler')) {
00387                 continue;
00388             }
00389             
00390             // Make a copy to preserve the state at time of error
00391             $variablesFiltered[$variableName] = $variables[$variableName];
00392         }
00393 
00394         $a_error = array('level' => $in_errno, 'message' => $in_errstr,
00395             'file' => $in_errfile, 'line' => $in_errline,
00396             'variables' => $variablesFiltered, 'signature' => $signature);
00397         $this->addError($a_error);
00398     }
00399 
00400     // }}}
00401     // {{{ _addReporter()
00402 
00416     function _addReporter($in_reporter, $in_level, $in_data = null)
00417     {
00418         $this->reporters[$in_reporter] = array('level' => $in_level, 'data' => $in_data); 
00419     }
00420 
00421     // }}}
00422     // {{{ _fatal()
00423 
00433     function _fatal($in_error)
00434     {
00435         echo '<html><body>';
00436         echo '<style>.errorBox { background-color: #ccc; border: thin dashed #000; font-weight: bold; text-align: center; } .errorMessage { color: red; } .errorNotice { margin-bottom: 10px; color: green; }</style>';
00437         echo '<div class="errorBox">';
00438         echo '<div class="errorNotice">' . _('A fatal error has occured') . '</div>';
00439         echo '<div class="errorMessage">' . $in_error['message'] . '</div>';
00440         if ($this->reporters['mail']['level'] & $in_error['level'] ||
00441             $this->reporters['file']['level'] & $in_error['level'] ||
00442             $this->reporters['system']['level'] & $in_error['level']) {
00443             echo '<div style="margin-top: 10px;">' . _('The details have been logged for the administrator') . '</div>';
00444         }
00445 
00446         echo '</div>';
00447         echo '</body></html>';
00448         exit;
00449     }
00450 
00451     // }}}
00452     // {{{ _processError()
00453 
00462     function _processError($in_error)
00463     {
00464         $message = $this->_getMessage($in_error);
00465 
00466         // syslog
00467         if ($this->reporters['system']['level'] & $in_error['level']) {
00468             @error_log(str_replace("\n", '', strip_tags($message)) . "\n", SYSTEM_LOG);
00469         }
00470 
00471         // file
00472         if ($this->reporters['file']['level'] & $in_error['level']) {
00473             @error_log(str_replace("\n", ' ', strip_tags($message)) . "\n", FILE_LOG, $this->reporters['file']['data']);
00474         }
00475 
00476         // stdout
00477         if ($this->reporters['stdout']['level'] & $in_error['level']) {
00478             echo $this->_cleanMessage($message . $this->_getDetails($in_error));
00479         }
00480 
00481         // redirect
00482         if ($this->reporters['redirect']['level'] & $in_error['level']) {
00483             echo '<script type="text/javascript">window.location.href = \'' . $this->reporters['redirect']['data'] . '\';</script>';
00484             exit;
00485         }
00486 
00487         // email
00488         if ($this->reporters['mail']['level'] & $in_error['level']) {
00489             $this->mailErrors[] = $message . $this->_getDetails($in_error);
00490         }
00491         
00492         // browser
00493         if ($this->reporters['browser']['level'] & $in_error['level']) {
00494             echo $message . $this->_getDetails($in_error);
00495         }
00496 
00497         // console
00498         if ($this->reporters['console']['level'] & $in_error['level']) {
00499             $this->consoleErrors[] = $this->_makeStringJSSafe($message . $this->_getDetails($in_error));
00500         }
00501     }
00502 
00503     // }}}
00504     // {{{ _getMessage()
00505 
00512     function _getMessage($in_error)
00513     {
00514         if ($in_error['level'] & E_ERROR_ALL) {
00515             $tmp_level = 'error';
00516         }
00517         elseif ($in_error['level'] & E_WARNING_ALL) {
00518             $tmp_level = 'warning';
00519         }
00520         elseif ($in_error['level'] & E_NOTICE_ALL) {
00521             $tmp_level = 'notice';
00522         }
00523         elseif ($in_error['level'] & E_DEBUG) {
00524             $tmp_level = 'debug';
00525         }
00526         elseif ($in_error['level'] & E_LOG) {
00527             $tmp_level = 'log';
00528         }
00529         else {
00530             $tmp_level = 'unknown';
00531         }
00532 
00533         $a_replace = array('%date%' => $in_error['date'], '%errorLevel%' => $tmp_level, 
00534                 '%file%' => $this->_getFileLink($in_error['file'], $in_error['line']), 
00535                 '%line%' => $in_error['line'], '%errorMessage%' => $in_error['message']);
00536         return str_replace(array_keys($a_replace), $a_replace, $this->templates['message']);
00537     }
00538 
00539     // }}}
00540     // {{{ _getDetails()
00541 
00550     function _getDetails($in_error)
00551     {
00552         $a_replace = array('%file%' => $this->_getFileLink($in_error['file'], $in_error['line']), 
00553                 '%line%' => $in_error['line'], '%ctxStart%' => $in_error['context']['start'], 
00554                 '%ctxEnd%' => $in_error['context']['end']);
00555         $s_message = str_replace(array_keys($a_replace), $a_replace, $this->templates['sourceMessage']);
00556         $a_replace = array('%header%' => $s_message, '%id%' => 'src_' . $in_error['signature']);
00557         $s_message = "\n" . str_replace(array_keys($a_replace), $a_replace, $this->templates['header']);
00558         // Highlight source and highlight the line with the problem
00559         $s_source = preg_replace("/(.*)(<font color.*?>{$in_error['line']}<\/font><.*?>:.*?<br \/>)/", 
00560                 '\\1<span style="background-color: #efbfbf;">\\2</span>', 
00561                 @highlight_string(stripslashes($in_error['context']['source']), true));
00562         $s_message .= str_replace('%source%', str_replace('  ', '&nbsp; ', str_replace('&nbsp;', ' ', $s_source)), $this->templates['source']);
00563         $s_message .= $this->_getBacktrace($in_error);
00564         $variables = $this->_exportVariables($in_error['variables'], $in_error['context']['variables'], $in_error['level']);
00565         if ($variables !== false) {
00566             $variables = @highlight_string(stripslashes('<?php' . $variables . '?>'), true);
00567             // strip the php tags
00568             $variables = preg_replace(':(&lt;\?php(<br />)*|\?&gt;):', '', $variables);
00569             $a_replace = array('%header%' => 'Variable scope report', '%id%' => 'var_' . $in_error['signature']);
00570             $s_message .= str_replace(array_keys($a_replace), $a_replace, $this->templates['header']);
00571             $s_message .= str_replace('%variable%', $variables, $this->templates['variable']);
00572         }
00573         
00574         return $s_message;
00575     }
00576 
00577     // }}}
00578     // {{{ _getBacktrace()
00579 
00588     function _getBacktrace($in_error)
00589     {
00590         // First two are always from the error handler.
00591         @array_shift($in_error['backtrace']);
00592         @array_shift($in_error['backtrace']);
00593         $s_message = '';
00594         if (count($in_error['backtrace'])) {
00595             $in_error['backtrace'] = array_reverse($in_error['backtrace']);
00596             $a_replace = array('%header%' => 'Backtrace report', '%id%' => 'bt_' . $in_error['signature']);
00597             $s_message = str_replace(array_keys($a_replace), $a_replace, $this->templates['header']);
00598             // All backtraces need to be in one big div for console js to work
00599             $s_message .= '<div>' . "\n";
00600             foreach ($in_error['backtrace'] as $k => $a_trace) {
00601                 if (isset($a_trace['class'])) {
00602                     $a_trace['function'] = $a_trace['class'] . $a_trace['type'] . $a_trace['function'];
00603                 }
00604 
00605                 $a_trace['function'] = '<span style="color: #0000cc;">' . $a_trace['function'] . '</span>';
00606                 $a_trace['function'] .= '<span style="color: #006600;">(</span>';
00607                 $a_trace['function'] .= isset($a_trace['args']) ? '<span style="color: #cc0000;">' . implode('</span>, <span style="color: #cc0000;">', $a_trace['args']) . '</span>' : '';
00608                 $a_trace['function'] .= '<span style="color: #006600;">)</span>';
00609 
00610                 $a_replace = array('%num%' => $k + 1, '%func%' => $a_trace['function'], 
00611                         '%line%' => $a_trace['line'], 
00612                         '%file%' => $this->_getFileLink($a_trace['file'], $a_trace['line']));
00613                 $s_message .= str_replace(array_keys($a_replace), $a_replace, $this->templates['backtrace']) . "\n";
00614             }
00615 
00616             $s_message .= "</div>\n";
00617         }
00618 
00619         return $s_message;
00620     }
00621 
00622     // }}}
00623     // {{{ _getContext()
00624 
00625     function _getContext($file, $line)
00626     {
00627         if (!@is_readable($file)) {
00628             return array('start' => 0, 'end' => 0, 'source' => '', 'variables' => array());
00629         }
00630 
00631         $fp = fopen($file, 'r');
00632         $start = max($line - $this->contextLines, 0);
00633         $end = $line + $this->contextLines;
00634         $lineNum = 0;
00635         $source = '';
00636         // Get context lines
00637         while ($lineNum < $end) {
00638             $lineNum++;
00639             if ($lineNum < $start) {
00640                 fgets($fp, 4096);
00641             }
00642             else {
00643                 $data = fgets($fp, 4096);
00644                 if (feof($fp)) {
00645                     break;
00646                 }
00647 
00648                 $source .= $lineNum . ': ' . $data; 
00649             }
00650         }
00651 
00652         fclose($fp);
00653         $source = $this->_addPhpTags($source);
00654         preg_match_all(';\$([[:alnum:]_]+);', $source, $matches);
00655         $variables = array_values(array_unique($matches[1]));
00656         return array('start' => $start + 1, 'end' => $lineNum,
00657             'source' => $source, 'variables' => $variables);
00658     }
00659 
00660     // }}}
00661     // {{{ _makeStringJSSafe()
00662 
00671     function _makeStringJSSafe($in_data)
00672     {
00673         return strtr($in_data, array("\t" => '\\t', "\n" => '\\n', "\r" => '\\r', '\\' => '&#092;', "'" => '&#39;'));
00674     }
00675 
00676     // }}}
00677     // {{{ _exportVariables()
00678 
00679     function _exportVariables(&$variables, $contextVariables, $level)
00680     {
00681         $variableString = '';
00682         foreach ($variables as $name => $contents) {
00683             // If we are using strict context and this variable is not in the context, skip it
00684             // When debugging always show the variable (this allows us to catch constants)
00685             if (!($level & E_DEBUG) && $this->strictContext && !in_array($name, $contextVariables)) {
00686                 continue;
00687             }
00688 
00689             // if this is an object and the class is in the exclude list, skip it
00690             if (is_object($contents) && in_array(get_class($contents), $this->classExcludeList)) {
00691                 continue;
00692             }
00693 
00694             $variableString .= '$' . $name . ' = ' . $this->_var_export($contents) . ';' . "\n";
00695         }
00696 
00697         if (empty($variableString)) {
00698             return false;
00699         }
00700         else {
00701             return "\n" . $variableString;
00702         }
00703     }
00704 
00705     // }}}
00706     // {{{ _strrpos2() 
00707 
00708     function _strrpos2($string, $needle, $offset = 0)
00709     {
00710         $addLen = strlen($needle);
00711         $endPos = $offset - $addLen;
00712 
00713         while (1) {
00714             if (($newPos = strpos($string, $needle, $endPos + $addLen)) === false) {
00715                 break;
00716             }
00717 
00718             $endPos = $newPos;
00719         }
00720 
00721         return ($endPos >= 0) ? $endPos : false;
00722     }
00723 
00724     // }}}
00725     // {{{ _addPhpTags()
00726 
00727     function _addPhpTags($source)
00728     {
00729         $startTag  = '<?php';
00730         $endTag = '?>';
00731 
00732         $firstStartPos  = ($pos = strpos($source, $startTag)) !== false ? $pos : -1;
00733         $firstEndPos = ($pos = strpos($source, $endTag)) !== false ? $pos : -1;
00734         
00735         // no tags found then it must be solid php since html can't throw a php error
00736         if ($firstStartPos < 0 && $firstEndPos < 0) {
00737             return $startTag . "\n" . $source . "\n" . $endTag;
00738         }
00739 
00740         // found an end tag first, so we are missing a start tag
00741         if ($firstEndPos >= 0 && ($firstStartPos < 0 || $firstStartPos > $firstEndPos)) {
00742             $source = $startTag . "\n" . $source;
00743         }
00744 
00745         $sourceLength = strlen($source);
00746         $lastStartPos  = ($pos = $this->_strrpos2($source, $startTag)) !== false ? $pos : $sourceLength + 1;
00747         $lastEndPos  = ($pos = $this->_strrpos2($source, $endTag)) !== false ? $pos : $sourceLength + 1;
00748 
00749         // See if we need to add an end tag
00750         if ($lastEndPos < $lastStartPos || ($lastEndPos > $lastStartPos && $lastEndPos > $sourceLength)) {
00751             $source .= $endTag;
00752         }
00753 
00754         return $source;
00755     }
00756 
00757     // }}}
00758     // {{{ _var_export()
00759 
00760     function _var_export(&$variable, $arrayIndent = '', $inArray = false, $level = 0)
00761     {
00762         static $maxLevels = 0, $followObjectReferences = false;
00763         if ($inArray != false) {
00764             $leadingSpace = '';
00765             $trailingSpace = ',' . "\n";
00766         }
00767         else {
00768             $leadingSpace = $arrayIndent;
00769             $trailingSpace = '';
00770         }
00771 
00772         $result = '';
00773         switch (gettype($variable)) {
00774             case 'object':
00775                 if ($inArray && !$followObjectReferences) {
00776                     $result = '*OBJECT REFERENCE*';
00777                     $trailingSpace = "\n";
00778                     break;
00779                 }
00780             case 'array':
00781                 if ($maxLevels && $level >= $maxLevels) {
00782                     $result = '** truncated, too much recursion **';
00783                 }
00784                 else {
00785                     $result = "\n" . $arrayIndent . 'array (' . "\n";
00786                     foreach ($variable as $key => $value) {
00787                         $result .= $arrayIndent . '  ' . (is_int($key) ? $key : ('\'' . str_replace('\'', '\\\'', $key) . '\'')) . ' => ' . $this->_var_export($value, $arrayIndent . '  ', true, $level + 1);
00788                      }
00789 
00790                     $result .= $arrayIndent . ')';
00791                 }
00792             break;
00793             case 'string':
00794                 $result = '\'' . str_replace('\'', '\\\'', $variable) . '\'';
00795             break;
00796             case 'boolean':
00797                 $result = $variable ? 'true' : 'false';
00798             break;
00799             case 'NULL':
00800                 $result = 'NULL';
00801             break;
00802             case 'resource':
00803                 $result = get_resource_type($variable);
00804             break;
00805             default:
00806                 $result = $variable;
00807             break;
00808         }
00809 
00810         return $leadingSpace . $result . $trailingSpace;
00811     }
00812 
00813     // }}}
00814     // {{{ _cleanMessage()
00815 
00816     function _cleanMessage($in_msg)
00817     {
00818         $in_msg = str_replace('<br />', "\n", $in_msg);
00819         $in_msg = str_replace('&nbsp;', ' ', $in_msg);
00820         $in_msg = strip_tags($in_msg);
00821         $in_msg = str_replace(get_html_translation_table(HTML_ENTITIES), array_keys(get_html_translation_table(HTML_ENTITIES)), $in_msg);
00822         return $in_msg;
00823     }
00824 
00825     // }}}
00826     // {{{ _getFileLink()
00827 
00828     function _getFileLink($in_file, $in_line)
00829     {
00830         if (!empty($this->fileUrl)) {
00831             $a_replace = array('%file%' => $in_file, '%line%' => $in_line);
00832             return '<a href="' . str_replace(array_keys($a_replace), $a_replace, $this->fileUrl) . 
00833                 '" target="_blank">' .  $in_file . '</a>';
00834         }
00835         else {
00836             return $in_file;
00837         }
00838     }
00839 
00840     // }}}
00841 }
00842 
00843 // {{{ php4_errorHandler()
00844 
00845 function php4_errorHandler() {
00846     if (func_num_args() == 0) {
00847         $GLOBALS['o_error']->__destructor();
00848     }
00849     else {
00850         $a = func_get_arg(0);
00851         $b = func_get_arg(1);
00852         $c = func_get_arg(2);
00853         $d = func_get_arg(3);
00854         $e = func_get_arg(4);
00855         $GLOBALS['o_error']->_trapError($a, $b, $c, $d, $e);
00856     }
00857 }
00858 
00859 // }}}
00860 ?>

Generated on Fri Jun 23 11:38:15 2006 for FastFrame by  doxygen 1.4.4