PHP: debug_backtrace - Manual

downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

debug_print_backtrace Errors and Logging

Last updated: Sat, 27 Jan 2007

view this page in

# debug_backtrace

(PHP 4 >= 4.3.0, PHP 5)

debug_backtrace -- Generates a backtrace

## Описание

array debug_backtrace ( void )

debug_backtrace() generates a PHP backtrace.

## Возвращаемые значения

Returns an associative array. The possible returned elements are as follows:

Таблица 1. Possible returned elements from debug_backtrace()

Name | Type | Description
--- | --- | ---
function | string | The current function name. See also __FUNCTION__.
line | integer | The current line number. See also __LINE__.
file | string | The current file name. See also __FILE__.
class | string | The current class name. See also __CLASS__
object | object | The current object.
type | string | The current call type. If a method call, "->" is returned. If a static method call, "::" is returned. If a function call, nothing is returned.
args | array | If inside a function, this lists the functions arguments. If inside an included file, this lists the included file name(s).

## Список изменений

Версия | Описание
--- | ---
5.1.1 | Added the current object as a possible return element.

## Примеры

Пример 1. debug_backtrace() example

`<?php
// filename: a.php
function a_test($str)
{
echo "\nHi: $str";
var_dump(debug_backtrace());
}
a_test('friend');
?>
<?php
// filename: b.php
include_once '/tmp/a.php';
?>`

Results similar to the following when executing `/tmp/b.php`:

    Hi: friend
    array(2) {
    [0]=>
    array(4) {
        ["file"] => string(10) "/tmp/a.php"
        ["line"] => int(10)
        ["function"] => string(6) "a_test"
        ["args"]=>
        array(1) {
          [0] => &string(6) "friend"
        }
    }
    [1]=>
    array(4) {
        ["file"] => string(10) "/tmp/b.php"
        ["line"] => int(2)
        ["args"] =>
        array(1) {
          [0] => string(10) "/tmp/a.php"
        }
        ["function"] => string(12) "include_once"
      }
    }

## Смотрите также

trigger_error()
debug_print_backtrace()

add a note User Contributed Notes
debug_backtrace
kroczu AT interia DOT pl
23-Jan-2007 10:24
`<?
// useful and comfortable debug function
// it's show memory usage and time flow between calls, so we can quickly find a block of code that need optimisation...
// example result:
/*
debug example.php> initialize
debug example.php> code-lines: 39-41 time: 2.0002 mem: 19 KB
debug example.php> code-lines: 41-44 time: 0.0000 mem: 19 KB
debug example.php> code-lines: 44-51 time: 0.6343 mem: 9117 KB
debug example.php> code-lines: 51-53 time: 0.1003 mem: 9117 KB
debug example.php> code-lines: 53-55 time: 0.0595 mem: 49 KB
*/
function debug()
{
static $start_time = NULL;
static $start_code_line = 0;
$call_info = array_shift( debug_backtrace() );
$code_line = $call_info['line'];
$file = array_pop( explode('/', $call_info['file']));
if( $start_time === NULL )
{
print "debug ".$file."> initialize\n";
$start_time = time() + microtime();
$start_code_line = $code_line;
return 0;
}
printf("debug %s> code-lines: %d-%d time: %.4f mem: %d KB\n", $file, $start_code_line, $code_line, (time() + microtime() - $start_time), ceil( memory_get_usage()/1024));
$start_time = time() + microtime();
$start_code_line = $code_line;
}
////////////////////////////////////////////////
// example:
debug();
sleep(2);
debug();
// soft-code...
$a = 3 + 5;
debug();
// hard-code
for( $i=0; $i<100000; $i++)
{
$dummy['alamakota'.$i] = 'alamakota'.$i;
}
debug();
usleep(100000);
debug();
unset($dummy);
debug();
?>`
seaside dot ki at mac dot com
14-Dec-2006 04:20
`I've started creating an external debug server for PHP. A PHP app require_once's a TADebugger(), which communicates with the debug sever. Find the OS X universal binary here [PHP source sample included]:
http://www.turingart.com/downloads/phpDebugger.zip
Currently, TADebugger allows to post these properties back to the debug server:
- Call backtraces
- String messages
- Source files, which were referenced by a backtrace call
Note, that the binary is a early version.`
icefragment at gmail dot com
23-Sep-2006 09:34
`A simple python-like backtrace. Note that I don't recurse into arrays if they are passed as arguments to functions.
function backtrace()
{
$bt = debug_backtrace();
echo("<br /><br />Backtrace (most recent call last):<br /><br />\n");
for($i = 0; $i <= count($bt) - 1; $i++)
{
if(!isset($bt[$i]["file"]))
echo("[PHP core called function]<br />");
else
echo("File: ".$bt[$i]["file"]."<br />");
if(isset($bt[$i]["line"]))
echo("&nbsp;&nbsp;&nbsp;&nbsp;line ".$bt[$i]["line"]."<br />");
echo("&nbsp;&nbsp;&nbsp;&nbsp;function called: ".$bt[$i]["function"]);
if($bt[$i]["args"])
{
echo("<br />&nbsp;&nbsp;&nbsp;&nbsp;args: ");
for($j = 0; $j <= count($bt[$i]["args"]) - 1; $j++)
{
if(is_array($bt[$i]["args"][$j]))
{
print_r($bt[$i]["args"][$j]);
}
else
echo($bt[$i]["args"][$j]);
if($j != count($bt[$i]["args"]) - 1)
echo(", ");
}
}
echo("<br /><br />");
}
}`
zmorris at mac dot com
20-Sep-2006 07:48
`Hi, I got tired of using a trace( $message, __FILE__, __LINE__ ) function I made. It forced me to include the file and line params (since php doesn't have macros) so I decided to make an alternative.
Simply call this new version using trace( 'my message' ); and it prints out a stack trace in a clearer way than the one stored in the debug_backtrace() array. It handles traces from outside of functions, traces in nested functions, and traces in included files, and also displays the function in a way that can be pasted right back into your php code for faster testing!
NOTE - be sure to save your files with the correct line endings for the line numbers to work correctly, which for Mac OS X is unix. You can get to this option in the popup menu in the toolbar at the top of each window in BBEdit.
<?php
function print_var( $var )
{
if( is_string( $var ) )
return( '"'.str_replace( array("\x00", "\x0a", "\x0d", "\x1a", "\x09"), array('\0', '\n', '\r', '\Z', '\t'), $var ).'"' );
else if( is_bool( $var ) )
{
if( $var )
return( 'true' );
else
return( 'false' );
}
else if( is_array( $var ) )
{
$result = 'array( ';
$comma = '';
foreach( $var as $key => $val )
{
$result .= $comma.print_var( $key ).' => '.print_var( $val );
$comma = ', ';
}
$result .= ' )';
return( $result );
}
return( var_export( $var, true ) ); // anything else, just let php try to print it
}
function trace( $msg )
{
echo "<pre>\n";
//var_export( debug_backtrace() ); echo "</pre>\n"; return; // this line shows what is going on underneath
$trace = array_reverse( debug_backtrace() );
$indent = '';
$func = '';
echo $msg."\n";
foreach( $trace as $val)
{
echo $indent.$val['file'].' on line '.$val['line'];
if( $func ) echo ' in function '.$func;
if( $val['function'] == 'include' ||
$val['function'] == 'require' ||
$val['function'] == 'include_once' ||
$val['function'] == 'require_once' )
$func = '';
else
{
$func = $val['function'].'(';
if( isset( $val['args'][0] ) )
{
$func .= ' ';
$comma = '';
foreach( $val['args'] as $val )
{
$func .= $comma.print_var( $val );
$comma = ', ';
}
$func .= ' ';
}
$func .= ')';
}
echo "\n";
$indent .= "\t";
}
echo "</pre>\n";
}
trace( 'error outside function' );
function test( $param1, $param2, $param3, $param4 )
{
trace( 'error in test()' );
}
test( 1.1, "param2\n", array( 1 => "a\n", "b\n" => 2 ), false );
?>`
admin at sgssweb dot com
13-Aug-2006 02:30
`Surprizingly, debug_backtrace() cannot aquire arguments from the function that is used as the second or later argument of a function.
<?php
function a($p) {
$backtrace = debug_backtrace();
if (isset($backtrace[0]['args']))
var_export($backtrace[0]['args']);
else
echo "Cannot aquire arguments";
echo "<br />";
return $p;
}
function b($p1, $p2, $p3) {
echo "$p1, $p2, $p3";
}
// This outputs:
// array ( 0 => 'First a', )
// Cannot aquire arguments
// Cannot aquire arguments
// First a, Second a, Third a
b(a("First a"), a("Second a"), a("Third a"));
?>`
tiwen at rpgame dot de
30-Apr-2006 01:25
`Another debug output. This is a short function that does not display the args (sometimes password are in arguments ...) and shows the callstack clearly in a table. In most cases i don't need more ...
<?php
function dieDebug($sError)
{
echo "<hr /><div>".$sError."<br /><table border='1'>";
$sOut=""; $aCallstack=debug_backtrace();
echo "<thead><tr><th>file</th><th>line</th><th>function</th>".
"</tr></thead>";
foreach($aCallstack as $aCall)
{
if (!isset($aCall['file'])) $aCall['file'] = '[PHP Kernel]';
if (!isset($aCall['line'])) $aCall['line'] = '';
echo "<tr><td>{$aCall["file"]}</td><td>{$aCall["line"]}</td>".
"<td>{$aCall["function"]}</td></tr>";
}
echo "</table></div><hr /></p>";
die();
}
?>
To use it, simply do something like this:
<?php
if(...) dieDebug("another error found!");
?>`
http://synergy8.com
13-Dec-2005 10:37
`It should be noted that if an internal php function such as call_user_func in the backtrace, the 'file' and 'line' entries will not be set.
Most debug tracers will use these entries. You should place a check to see if the key exists in the array before using this function. Otherwise notices will be generated.
<?php
$arrTrace = debug_backtrace();
foreach ($arrTrace as $arr)
{
if (!isset ($arr['file']))
{
$arr['file'] = '[PHP Kernel]';
}
if (!isset ($arr['line']))
{
$arr['line'] = '';
}
// Do something
}
?>`
tb
21-Jul-2005 11:18
`I use this for debugging in my object oriented systems. It allows me to output a debug/error/warning function with exact information about the location that the error was thrown, which is useful. Check it:
<?php
abstract class Debugger {
/**
* Throw a debug message.
*/
abstract function debug($msg);
/**
* Throw an error message.
*/
abstract function error($msg);
/**
* Throw a warning message.
*/
abstract function warning($msg);
/**
* Wrap a message with information about class, function, file and line
* number and return it.
*/
protected function getMsg($msg) {
$bt = debug_backtrace();
// get class, function called by caller of caller of caller
$class = $bt[2]['class'];
$function = $bt[2]['function'];
// get file, line where call to caller of caller was made
$file = $bt[1]['file'];
$line = $bt[1]['line'];
// build & return the message
return "$class::$function: $msg in $file at $line";
}
}
?>
Implement different debuggers for different scenarios (development, testing, production). Each debugger extends Debugger; each of its methods (debug/error/warning) calls $this->getMsg($msg) to get a message with class, function, file, and line information. Then it can either log it, email it, die with it, etc.
Then, just give each object (perhaps using a common superclass Object) a concrete debugger. Then, from any object method, do something like:
<?php
class Foo extends Object {
function bar() {
$this->debugger->error("This is an error");
}
}
?>
Which produces something like:
Foo::bar: This is an error in /some/file at X`
diz at ysagoon dot com
24-Nov-2004 02:35
`Ok as spagmoid already said, I just realized that my function has a similar bug than jlim's function.
So just add the following line:
if (is_array($bt['args']))
before line:
foreach ($bt['args'] as $a) {
This way you avoid the warning from being displayed.`
diz at ysagoon dot com
23-Nov-2004 02:40
`And here are my two cents for a useful and good looking backtrace function.
<?php
function backtrace()
{
$output = "<div style='text-align: left; font-family: monospace;'>\n";
$output .= "<b>Backtrace:</b><br />\n";
$backtrace = debug_backtrace();
foreach ($backtrace as $bt) {
$args = '';
foreach ($bt['args'] as $a) {
if (!empty($args)) {
$args .= ', ';
}
switch (gettype($a)) {
case 'integer':
case 'double':
$args .= $a;
break;
case 'string':
$a = htmlspecialchars(substr($a, 0, 64)).((strlen($a) > 64) ? '...' : '');
$args .= "\"$a\"";
break;
case 'array':
$args .= 'Array('.count($a).')';
break;
case 'object':
$args .= 'Object('.get_class($a).')';
break;
case 'resource':
$args .= 'Resource('.strstr($a, '#').')';
break;
case 'boolean':
$args .= $a ? 'True' : 'False';
break;
case 'NULL':
$args .= 'Null';
break;
default:
$args .= 'Unknown';
}
}
$output .= "<br />\n";
$output .= "<b>file:</b> {$bt['line']} - {$bt['file']}<br />\n";
$output .= "<b>call:</b> {$bt['class']}{$bt['type']}{$bt['function']}($args)<br />\n";
}
$output .= "</div>\n";
return $output;
}
?>
And here's a sample of how the output looks like (the last call is on the top):
Backtrace:
file: 56 - /tmp/test.php
call: backtrace()
file: 53 - /tmp/test.php
call: test->bar(15.4, Array(4))
file: 61 - /tmp/test.php
call: test->test("making new object", True)
file: 65 - /tmp/test.php
call: foo(Resource(#2), Null)`
ad-rotator.com
30-Apr-2004 09:11
`To simply print out the file/function trace (chain of calls, file and line number before the error):
function getTrace() {
$vDebug = debug_backtrace();
$vFiles = array();
for ($i=0;$i<count($vDebug);$i++) {
// skip the first one, since it's always this func
if ($i==0) { continue; }
$aFile = $vDebug[$i];
$vFiles[] = '('.basename($aFile['file']).':'.$aFile['line'].')';
} // for
$vTraceStr = implode(',',$vFiles);
}`
spagmoid at yahoo dot NOSPAMcom
09-Dec-2003 11:47
`ATTN: jlim#natsoft.com.my
Great function, but you have a few bugs.
At the line:
foreach($arr['args'] as $v)
Change it to:
$args = array();
if(!empty($arr['args'])) foreach($arr['args'] as $v)
And since line & file are not present in the array if calling from the error handler,
$Line = (isset($arr['line'])? $arr['line'] : "unknown");
$File = (isset($arr['file'])? $arr['file'] : "unknown");
and substitute accordingly.
Here's my version of it, alas with different formatting:
----------------------------------------
function DBG_GetBacktrace()
{
$s = '';
$MAXSTRLEN = 64;
$s = '<pre align=left>';
$traceArr = debug_backtrace();
array_shift($traceArr);
$tabs = sizeof($traceArr)-1;
foreach($traceArr as $arr)
{
for ($i=0; $i < $tabs; $i++) $s .= ' &nbsp; ';
$tabs -= 1;
$s .= '<font face="Courier New,Courier">';
if (isset($arr['class'])) $s .= $arr['class'].'.';
$args = array();
if(!empty($arr['args'])) foreach($arr['args'] as $v)
{
if (is_null($v)) $args[] = 'null';
else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
else if (is_object($v)) $args[] = 'Object:'.get_class($v);
else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
else
{
$v = (string) @$v;
$str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
if (strlen($v) > $MAXSTRLEN) $str .= '...';
$args[] = "\"".$str."\"";
}
}
$s .= $arr['function'].'('.implode(', ',$args).')</font>';
$Line = (isset($arr['line'])? $arr['line'] : "unknown");
$File = (isset($arr['file'])? $arr['file'] : "unknown");
$s .= sprintf("<font color=#808080 size=-1> # line %4d, file: <a href=\"file:/%s\">%s</a></font>",
$Line, $File, $File);
$s .= "\n";
}
$s .= '</pre>';
return $s;
}`
Fabian dot Kraetzer at gmx dot de
01-Sep-2003 06:18
`I coded a function, too. Just call debug() evertime you think you could encounter an error:
<?
function debug()
{
$debug_array = debug_backtrace();
$counter = count($debug_array);
for($tmp_counter = 0; $tmp_counter != $counter; ++$tmp_counter)
{
?>
<table width="558" height="116" border="1" cellpadding="0" cellspacing="0" bordercolor="#000000">
<tr>
<td height="38" bgcolor="#D6D7FC"><font color="#000000">function <font color="#FF3300"><?
echo($debug_array[$tmp_counter]["function"]);?>(</font> <font color="#2020F0"><?
//count how many args a there
$args_counter = count($debug_array[$tmp_counter]["args"]);
//print them
for($tmp_args_counter = 0; $tmp_args_counter != $args_counter; ++$tmp_args_counter)
{
echo($debug_array[$tmp_counter]["args"][$tmp_args_counter]);
if(($tmp_args_counter + 1) != $args_counter)
{
echo(", ");
}
else
{
echo(" ");
}
}
?></font><font color="#FF3300">)</font></font></td>
</tr>
<tr>
<td bgcolor="#5F72FA"><font color="#FFFFFF">{</font><br>
<font color="#FFFFFF">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file: <?
echo($debug_array[$tmp_counter]["file"]);?></font><br>
<font color="#FFFFFF">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line: <?
echo($debug_array[$tmp_counter]["line"]);?></font><br>
<font color="#FFFFFF">}</font></td>
</tr>
</table>
<?
if(($tmp_counter + 1) != $counter)
{
echo("<br>was called by:<br>");
}
}
exit();
}
?>`
bernyregeling AT hotmail DOT com
08-Aug-2003 04:29
`I wrote this function, in addition to jlim, for a nice NO-HTML output.
Thee result has similarities to a Java-error. Hope you like it.
(BTW, this function exits the script too, if debug_backtrace is displayed)
------------------------------
function debug_bt()
{
if(!function_exists('debug_backtrace'))
{
echo 'function debug_backtrace does not exists'."\r\n";
return;
}
//echo '<pre>';
echo "\r\n".'----------------'."\r\n";
echo 'Debug backtrace:'."\r\n";
echo '----------------'."\r\n";
foreach(debug_backtrace() as $t)
{
echo "\t" . '@ ';
if(isset($t['file'])) echo basename($t['file']) . ':' . $t['line'];
else
{
// if file was not set, I assumed the functioncall
// was from PHP compiled source (ie XML-callbacks).
echo '<PHP inner-code>';
}
echo ' -- ';
if(isset($t['class'])) echo $t['class'] . $t['type'];
echo $t['function'];
if(isset($t['args']) && sizeof($t['args']) > 0) echo '(...)';
else echo '()';
echo "\r\n";
}
//echo '</pre>';
exit;
}`
jlim#natsoft.com.my
13-Mar-2003 05:51
`Pretty print the backtrace(). Functions are indented based on call value, and file is linked using file:// for convenience.
Enjoy, John Lim
function adodb_backtrace($print=true)
{
$s = '';
if (PHPVERSION() >= 4.3) {
$MAXSTRLEN = 64;
$s = '<pre align=left>';
$traceArr = debug_backtrace();
array_shift($traceArr);
$tabs = sizeof($traceArr)-1;
foreach ($traceArr as $arr) {
for ($i=0; $i < $tabs; $i++) $s .= ' &nbsp; ';
$tabs -= 1;
$s .= '<font face="Courier New,Courier">';
if (isset($arr['class'])) $s .= $arr['class'].'.';
foreach($arr['args'] as $v) {
if (is_null($v)) $args[] = 'null';
else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
else if (is_object($v)) $args[] = 'Object:'.get_class($v);
else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
else {
$v = (string) @$v;
$str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
if (strlen($v) > $MAXSTRLEN) $str .= '...';
$args[] = $str;
}
}
$s .= $arr['function'].'('.implode(', ',$args).')';
$s .= sprintf("</font><font color=#808080 size=-1> # line %4d,".
" file: <a href=\"file:/%s\">%s</a></font>",
$arr['line'],$arr['file'],$arr['file']);
$s .= "\n";
}
$s .= '</pre>';
if ($print) print $s;
}
return $s;
}`
add a note
debug_print_backtrace Errors and Logging

Last updated: Sat, 27 Jan 2007
show source | credits | stats | sitemap | contact | advertising | mirror sites
Copyright © 2001-2007 The PHP Group
All rights reserved.
This mirror generously provided by: Yahoo! Inc.
Last updated: Sat Mar 10 11:33:19 2007 PST