PHPCon Poland 2024

debug_print_backtrace

(PHP 5, PHP 7, PHP 8)

debug_print_backtraceBir hata izleme raporu basar

Açıklama

debug_print_backtrace(int $seçenekler = 0, int $sınır = 0): void

debug_print_backtrace() bir PHP hata izleme raporu (backtrace) basar. İşlev çağrılarını, include/require ile dahil edilen dosyaları ve eval() kodlarını basar.

Bağımsız Değişkenler

seçenekler

Aşağıdaki seçeneklerin bit maskesidir:

debug_print_backtrace() seçenekleri
DEBUG_BACKTRACE_IGNORE_ARGS Bellek kazanmak için "args" indisinin ve dolayısıyla tüm işlev/yöntem bağımsız değişkenlerinin atlanıp atlanmayacağı.

sınır

Bu bağımsız değişken döndürülecek yığıt çerçevelerinin sayısını sınırlamak için kullanılmaktadır. Öntanımlı değer, tüm yığıt çerçevelerinin dönmesini sağlayan 0 değeridir.

Dönen Değerler

Hiçbir değer dönmez.

Örnekler

Örnek 1 - debug_print_backtrace() örneği

<?php
// include.php dosyası

function a() {
b();
}

function
b() {
c();
}

function
c(){
debug_print_backtrace();
}

a();

?>
<?php
// test.php dosyası
// Bu dosya çalıştırılacak.

include 'include.php';
?>

Yukarıdaki örnek şuna benzer bir çıktı üretir:

#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]

Ayrıca Bakınız

add a note

User Contributed Notes 5 notes

up
86
bishop
14 years ago
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()));
?>
up
25
dany dot dylan at gmail dot com
15 years ago
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/", '', $trace, 1);

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

return
$trace;
}
?>
up
-3
David Spector
3 years ago
If your show your error messages in HTML (with suitable safety using entities), this function won't work nicely because it uses newlines for formatting.

Here is a function that works similarly, but using <BR> tags. Insert it near the beginning of your program to add a stack to Warning output only, or modify it as you like:

// Here is code for error stack output in HTML:
function error_handler_callback($errno,$message,$file,$line,$context)
{
if ($errno === E_WARNING)
echo "Stack, innermost first:<br>".nl2br((new Exception())->getTraceAsString());
return false; // to execute the regular error handler
}
set_error_handler("error_handler_callback");
up
-11
chris dot kistner at gmail dot com
14 years ago
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_ignore, 3, ' ')
.
$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($key, chr(0)) !== false) {
$key = ''; // Private variable found
}
$args[] = '['.$key.'] => '.get_arg($value);
}

$arg = get_class($arg) . ' Object ('.implode(',', $args).')';
}
}
?>
up
-12
AB
8 years ago
This code will give you a simple horizontal stack trace to assist debugging:

<?php

class A {
public function
testA() {
echo
"<LI>Class A.testA ----??";
echo
"<LI>".$this->whoDidThat();
}
public function
whoDidThat() {
$who=debug_backtrace();
$result="";
$count = 0;
$last=count($who);
foreach(
$who as $k=>$v) {
if (
$count++ > 0) {
$x="";
if (
$count>2) {
$x=">";
}
$result="[line".$who[$k]['line']."]".$who[$k]['class'].".".$who[$k]['function'].$x.$result;
}
}
return
$result;
}
}
class
B extends A {
public function
testB() {
echo
"<LI>Class B.testB";
echo
"<LI>".$this->whoDidThat();
}
public function
testA() {
echo
"<LI>Class testB.testA ---- Y";
echo
"<LI>".$this->whoDidThat();
}
}
class
C {
public function
test() {
echo
"<HR>";
$b=new B();
echo
"<HR>Class C calling B.testA";
$b->testA();
}
}

$c=new C();
$c->test();
echo
debug_print_backtrace();
?>

When run you get

Class C calling B.testA
*Class testB.testA ---- Y
*[line45]C.test>[line40]B.testA
To Top