How can I get PHP to produce a backtrace upon errors?

后端 未结 11 1985
無奈伤痛
無奈伤痛 2020-11-28 23:29

Trying to debug PHP using its default current-line-only error messages is horrible. How can I get PHP to produce a backtrace (stack trace) when errors are produced?

相关标签:
11条回答
  • 2020-11-29 00:06
    $backtrace = debug_backtrace();
    

    i wrote a little article about backtracing a while back

    0 讨论(0)
  • 2020-11-29 00:10

    As php debug extensions, there is Xdebug and PHP DBG. Each one has its advantages and disadvantages.

    0 讨论(0)
  • 2020-11-29 00:11

    My script for installing an error handler that produces a backtrace:

    <?php
    function process_error_backtrace($errno, $errstr, $errfile, $errline, $errcontext) {
        if(!(error_reporting() & $errno))
            return;
        switch($errno) {
        case E_WARNING      :
        case E_USER_WARNING :
        case E_STRICT       :
        case E_NOTICE       :
        case E_USER_NOTICE  :
            $type = 'warning';
            $fatal = false;
            break;
        default             :
            $type = 'fatal error';
            $fatal = true;
            break;
        }
        $trace = array_reverse(debug_backtrace());
        array_pop($trace);
        if(php_sapi_name() == 'cli') {
            echo 'Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ':' . "\n";
            foreach($trace as $item)
                echo '  ' . (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()' . "\n";
        } else {
            echo '<p class="error_backtrace">' . "\n";
            echo '  Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ':' . "\n";
            echo '  <ol>' . "\n";
            foreach($trace as $item)
                echo '    <li>' . (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()</li>' . "\n";
            echo '  </ol>' . "\n";
            echo '</p>' . "\n";
        }
        if(ini_get('log_errors')) {
            $items = array();
            foreach($trace as $item)
                $items[] = (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()';
            $message = 'Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ': ' . join(' | ', $items);
            error_log($message);
        }
        if($fatal)
            exit(1);
    }
    
    set_error_handler('process_error_backtrace');
    ?>
    

    Caveat: it is powerless to affect various 'PHP Fatal Errors', since Zend in their wisdom decided that these would ignore set_error_handler(). So you still get useless final-location-only errors with those.

    0 讨论(0)
  • 2020-11-29 00:12

    set_error_handler() + debug_backtrace() + debug_print_backtrace() in PHP5

    0 讨论(0)
  • 2020-11-29 00:13

    This is how you do it:

    set_error_handler(function($errorType){
        if(error_reporting() & $errorType){
            ?><pre><?
            debug_print_backtrace();
            ?></pre><?
        }
    }) ;
    

    It requires PHP 5.3+ since it uses a closure. If you need lower PHP support just convert the closure to a normal function.

    0 讨论(0)
  • 2020-11-29 00:17

    Xdebug prints a backtrace table on errors, and you don't have to write any PHP code to implement it.

    Downside is you have to install it as a PHP extension.

    0 讨论(0)
提交回复
热议问题