How can I get PHP to produce a backtrace upon erro

2019-01-06 10:23发布

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条回答
做自己的国王
2楼-- · 2019-01-06 11:02

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

查看更多
Juvenile、少年°
3楼-- · 2019-01-06 11:02

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.

查看更多
走好不送
4楼-- · 2019-01-06 11:06

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.

查看更多
叼着烟拽天下
5楼-- · 2019-01-06 11:07

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.

查看更多
孤傲高冷的网名
6楼-- · 2019-01-06 11:10
$backtrace = debug_backtrace();

i wrote a little article about backtracing a while back

查看更多
兄弟一词,经得起流年.
7楼-- · 2019-01-06 11:13

PHP DeBugger also does a back trace similiar to PHP Error with more options.
If you want you can easily make your own with set_error_handler and debug_backtrace

set_error_handler ($error_handler, error_reporting);
/**
 * @var int $errno the error number
 * @var string $errstr the error message
 * @var string $errfile the error file
 * @var int $errline the line of the error
 */
$error_handler = function($errno, $errstr, $errfile, $errline){
    $trace = debug_backtrace();
    array_shift($backtrace);//remove the stack about this handler
    foreach($trace as $k => $v){
        //parse your backtrace
    }
}

Also note that for internal stacks in the backtrace some of the keys will not be set. Be sure to check if the key exist before you do something with it if you have all errors on :)

查看更多
登录 后发表回答