错误处理 函数
在线手册:中文  英文

debug_print_backtrace

(PHP 5)

debug_print_backtrace 打印一条回溯。

说明

void debug_print_backtrace ([ int $options = 0 [, int $limit = 0 ]] )

debug_print_backtrace() 打印了一条 PHP 回溯。它打印了函数调用、被 included/required 的文件和 eval() 的代码。

参数

options

截至 5.3.6,这个参数是以下选项的位掩码:

debug_print_backtrace() 选项
DEBUG_BACKTRACE_IGNORE_ARGS 是否忽略 "args" 的索引,包括所有的 function/method 的参数,能够节省内存开销。

limit

截至 5.4.0,这个参数能够用于限制返回堆栈帧的数量。 默认为 (limit=0) ,返回所有的堆栈帧。

返回值

没有返回值。

更新日志

版本 说明
5.4.0 添加了可选的参数 limit
5.3.6 添加了可选的参数 options

范例

Example #1 debug_print_backtrace() 范例

<?php
// include.php file

function a() {
    
b();
}

function 
b() {
    
c();
}

function 
c(){
    
debug_print_backtrace();
}

a();

?>
<?php
// 文件 test.php
// 这是你应该运行的文件

include 'include.php';
?>

以上例程的输出类似于:

#0  c() called at [/tmp/include.php:10]
#1  b() called at [/tmp/include.php:6]
#2  a() called at [/tmp/include.php:17]
#3  include(/tmp/include.php) called at [/tmp/test.php:3]

参见


错误处理 函数
在线手册:中文  英文

用户评论:

Sammaye (2011-02-24 04:26:18)

Most methods of getting the backtrace and printing are susceptible to a certain runtime flaw.

If the user is able to produce 100+ errors this will throw an error which in turn will throw 100+ errors on each nest of get_args() creating an infinite loop and eventually downing your server.

If you are looking for a simple backtrace that (so far) will not fall to this error then use this:

<?php
    
foreach(debug_backtrace() as $k=>$v){
        if(
$v['function'] == "include" || $v['function'] == "include_once" || $v['function'] == "require_once" || $v['function'] == "require"){
            
$backtracel .= "#".$k." ".$v['function']."(".$v['args'][0].") called at [".$v['file'].":".$v['line']."]<br />";
        }else{
            
$backtracel .= "#".$k." ".$v['function']."() called at [".$v['file'].":".$v['line']."]<br />";
        }
    }
?>

chris dot kistner at gmail dot com (2010-04-01 04:31:43)

Here's a function that returns a string with the same information shown in debug_print_backtrace(), with the option to exclude a certain amount of traces (by altering the $traces_to_ignore argument).

I've done a couple of tests to ensure that it prints exactly the same information, but I might have missed something.

This solution is a nice workaround to get the debug_print_backtrace() information if you're already using ob_start() in your PHP code.

<?php
function get_debug_print_backtrace($traces_to_ignore 1){
    
$traces debug_backtrace();
    
$ret = array();
    foreach(
$traces as $i => $call){
        if (
$i $traces_to_ignore ) {
            continue;
        }

        
$object '';
        if (isset(
$call['class'])) {
            
$object $call['class'].$call['type'];
            if (
is_array($call['args'])) {
                foreach (
$call['args'] as &$arg) {
                    
get_arg($arg);
                }
            }
        }        

        
$ret[] = '#'.str_pad($i $traces_to_ignore3' ')
        .
$object.$call['function'].'('.implode(', '$call['args'])
        .
') called at ['.$call['file'].':'.$call['line'].']';
    }

    return 
implode("\n",$ret);
}

function 
get_arg(&$arg) {
    if (
is_object($arg)) {
        
$arr = (array)$arg;
        
$args = array();
        foreach(
$arr as $key => $value) {
            if (
strpos($keychr(0)) !== false) {
                
$key '';    // Private variable found
            
}
            
$args[] =  '['.$key.'] => '.get_arg($value);
        }

        
$arg get_class($arg) . ' Object ('.implode(','$args).')';
    }
}
?>

bishop (2009-07-28 13:20:13)

Another way to manipulate and print a backtrace, without using output buffering:

<?php
// print backtrace, getting rid of repeated absolute path on each file
$e = new Exception();
print_r(str_replace('/path/to/code/'''$e->getTraceAsString()));
?>

bradley dot giesbrecht at gmail dot com (2009-01-13 16:51:52)

I was using the function by dany dot dylan at gmail dot com and found that preg_replace had string length limits. So here is yet another output format function.

<?php
if ( !function_exists "mydie" ) ) { 
    function 
mydie (  ) { $this_file __FILE__ $this_line __LINE__ 
        
$buffer = array (  ) ; 
        
$trace_calls "" 
        
ob_start (  ) ; 
        
debug_print_backtrace (  ) ; 
        
$buffer"0" ] = ob_get_contents (  ) ; 
        
ob_end_clean (  ) ; 
        
$buffer"0" ] = array_slice explode "#" $buffer"0" ] ) , , -false ) ; 
        foreach ( 
$buffer"0" ] as $key => $value ) { 
            
$value explode ") called at [" $value ) ; 
            if ( 
$key == ) { 
                
$value"0" ] = "0  " __FUNCTION__ "(see above vars)" 
            } 
            
$trace_calls .= "#" implode ")\n\tcalled at [" $value ) ;
        } 
        unset ( 
$buffer $key $value ) ; 
        echo 
"<pre>function " __FUNCTION__ " lives here:{$this_file}:{$this_line}</pre>" 
        echo ( 
"<pre>" print_rfunc_get_args (  ) , true ) . "</pre>" ) ;     
        if ( 
$trace_calls == "" $trace_calls "No functions were called." 
        echo ( 
"<pre>" $trace_calls "</pre>" ) ;     
        die ; 
    } 
}
function 
(  ) { 
    
func_get_args (  ) , ) ; 
}
function 
(  ) { 
    
func_get_args (  ) , ) ; 
}
function 
(  ) { 
    
mydie func_get_args (  ) , ) ; 
}
) ; 
?>

## outputs 
function mydie lives here:/path/file.php:4
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => Array
                        (
                            [0] => 1
                        )

                    [1] => 2
                )

            [1] => 3
        )

    [1] => 4
)
#0  mydie(see above vars))
    called at [/path/file.php:54]
#1  c(Array ([0] => Array ([0] => 1),[1] => 2), 3)
    called at [/path/file.php:49]
#2  b(Array ([0] => 1), 2)
    called at [/path/file.php:43]

dany dot dylan at gmail dot com (2008-11-10 21:51:21)

I like the output of debug_print_backtrace() but I sometimes want it as a string.

bortuzar's solution to use output buffering is great, but I'd like to factorize that into a function.  Doing that however always results in whatever function name I use appearing at the top of the stack which is redundant.

Below is my noddy (simple) solution.  If you don't care for renumbering the call stack, omit the second preg_replace().

<?php
    
function debug_string_backtrace() {
        
ob_start();
        
debug_print_backtrace();
        
$trace ob_get_contents();
        
ob_end_clean();

        
// Remove first item from backtrace as it's this function which
        // is redundant.
        
$trace preg_replace ('/^#0\s+' __FUNCTION__ "[^\n]*\n/"''$trace1);

        
// Renumber backtrace items.
        
$trace preg_replace ('/^#(\d+)/me''\'#\' . ($1 - 1)'$trace);

        return 
$trace;
    }
?>

harmor (2008-02-19 13:54:09)

Input (Using: PHP Version 5.2.5-pl1-gentoo):
<?php
class CTest
{
    public static function 
say($a_szVar)
    {
        
debug_print_backtrace();
        echo 
'<br />';
    }
}

CTest::say('static call');

$obj = new CTest;
$obj->say('object call');
    
?>

Output:
#0 CTest::say(static call) called at [C:\PHPDocument4.php:11]
#0 CTest::say(object call) called at [C:\PHPDocument4.php:15]

Notice that the second line of the output outputs "::" instead of "->" when calling the function using an object.

taner (2007-08-21 04:52:03)

bortuzar: a simpler version, w/o output buffering:

<?php

$query 
sprintf("INSERT INTO EventLog (Trace) VALUES ('%s')",
    
mysql_real_escape_string(join("\n"debug_backtrace())) );
mysql_query($query);

?>

bortuzar at gmail dot com (2007-06-05 11:23:07)

If you want to get the trace into a variable or DB, I suggest to do the following:

<?php
    ob_start
();
        
debug_print_backtrace();
    
$trace ob_get_contents();
    
ob_end_clean();

$query sprintf("INSERT INTO EventLog (Trace) VALUES ('%s')",
            
mysql_real_escape_string($trace));
mysql_query($query);
?>

petermarkellis at googlemail dot com (2007-03-28 02:10:37)

A cleaner example:
<?php
function a() {
   
b();
}

function 
b() {
   
c();
}

function 
c(){
   
debug_print_backtrace();
}

a();

?>

outputs:
#0  c() called at [C:\debugbacktracetest.php:7]
#1  b() called at [C:\debugbacktracetest.php:3]
#2  a() called at [C:\debugbacktracetest.php:14]

aidan at php dot net (2005-03-15 01:47:24)

This functionality is now implemented in the PEAR package PHP_Compat.
More information about using this function without upgrading your version of PHP can be found on the below link:
http://pear.php.net/package/PHP_Compat

易百教程