Php display stack trace

Exception::getTraceAsString

Honestly, Exception::getTraceAsString() simply sucks, listing only the called method (below, for example, on line 89 function fail2() gets called, but there’s no information that you have the originator is fail1()). The fact that, in the example below, the exception gets thrown on line 78, is completely omitted from the trace and only available within the exception. Chained exceptions are not supported as well.

Example:
#0 /var/htdocs/websites/sbdevel/public/index.php(70): seabird\test\C->exc()
#1 /var/htdocs/websites/sbdevel/public/index.php(85): seabird\test\C->doexc()
#2 /var/htdocs/websites/sbdevel/public/index.php(89): seabird\test\fail2()
#3 /var/htdocs/websites/sbdevel/public/index.php(93): seabird\test\fail1()
#4

jTraceEx() provides a much better java-like stack trace that includes support for chained exceptions:
Exception: Thrown from class C
at seabird.test.C.exc(index.php:78)
at seabird.test.C.doexc(index.php:70)
at seabird.test.fail2(index.php:85)
at seabird.test.fail1(index.php:89)
at (main)(index.php:93)
Caused by: Exception: Thrown from class B
at seabird.test.B.exc(index.php:64)
at seabird.test.C.exc(index.php:75)
. 4 more
Caused by: Exception: Thrown from class A
at seabird.test.A.exc(index.php:46)
at seabird.test.B.exc(index.php:61)
. 5 more

(see at the end for the example code)

/**
* jTraceEx() — provide a Java style exception trace
* @param $exception
* @param $seen — array passed to recursive calls to accumulate trace lines already seen
* leave as NULL when calling this function
* @return array of strings, one entry per trace line
*/
function jTraceEx ( $e , $seen = null ) $starter = $seen ? ‘Caused by: ‘ : » ;
$result = array();
if (! $seen ) $seen = array();
$trace = $e -> getTrace ();
$prev = $e -> getPrevious ();
$result [] = sprintf ( ‘%s%s: %s’ , $starter , get_class ( $e ), $e -> getMessage ());
$file = $e -> getFile ();
$line = $e -> getLine ();
while ( true ) $current = » $file : $line » ;
if ( is_array ( $seen ) && in_array ( $current , $seen )) $result [] = sprintf ( ‘ . %d more’ , count ( $trace )+ 1 );
break;
>
$result [] = sprintf ( ‘ at %s%s%s(%s%s%s)’ ,
count ( $trace ) && array_key_exists ( ‘class’ , $trace [ 0 ]) ? str_replace ( ‘\\’ , ‘.’ , $trace [ 0 ][ ‘class’ ]) : » ,
count ( $trace ) && array_key_exists ( ‘class’ , $trace [ 0 ]) && array_key_exists ( ‘function’ , $trace [ 0 ]) ? ‘.’ : » ,
count ( $trace ) && array_key_exists ( ‘function’ , $trace [ 0 ]) ? str_replace ( ‘\\’ , ‘.’ , $trace [ 0 ][ ‘function’ ]) : ‘(main)’ ,
$line === null ? $file : basename ( $file ),
$line === null ? » : ‘:’ ,
$line === null ? » : $line );
if ( is_array ( $seen ))
$seen [] = » $file : $line » ;
if (! count ( $trace ))
break;
$file = array_key_exists ( ‘file’ , $trace [ 0 ]) ? $trace [ 0 ][ ‘file’ ] : ‘Unknown Source’ ;
$line = array_key_exists ( ‘file’ , $trace [ 0 ]) && array_key_exists ( ‘line’ , $trace [ 0 ]) && $trace [ 0 ][ ‘line’ ] ? $trace [ 0 ][ ‘line’ ] : null ;
array_shift ( $trace );
>
$result = join ( «\n» , $result );
if ( $prev )
$result .= «\n» . jTraceEx ( $prev , $seen );

Читайте также:  Php if statement syntax

return $result ;
>
?>

Here’s the example code:
class A public function exc () throw new \ Exception ( ‘Thrown from class A’ ); // >
>

class B public function exc () try $a = new A ;
$a -> exc (); // >
catch(\ Exception $e1 ) throw new \ Exception ( ‘Thrown from class B’ , 0 , $e1 ); // >
>
>
class C public function doexc () $this -> exc (); // >
public function exc () try $b = new B ;
$b -> exc (); // >
catch(\ Exception $e1 ) throw new \ Exception ( ‘Thrown from class C’ , 0 , $e1 ); // >
>
>

Источник

debug_print_backtrace

debug_print_backtrace() prints a PHP backtrace. It prints the function calls, included/required files and eval() ed stuff.

Parameters

This parameter is a bitmask for the following options:

debug_print_backtrace() options
DEBUG_BACKTRACE_IGNORE_ARGS Whether or not to omit the «args» index, and thus all the function/method arguments, to save memory.

This parameter can be used to limit the number of stack frames printed. By default ( limit = 0 ) it prints all stack frames.

Return Values

Examples

Example #1 debug_print_backtrace() example

function c () debug_print_backtrace ();
>

// test.php file
// this is the file you should run

The above example will output something similar to:

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

See Also

User Contributed Notes 5 notes

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

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

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.

Читайте также:  Css горизонтальная прокрутка flex

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

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 );

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 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:
«.nl2br((new Exception())->getTraceAsString());
return false; // to execute the regular error handler
>
set_error_handler(«error_handler_callback»);

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.

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’ ]. ‘]’ ;
>

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 );
>

Читайте также:  Sending mail form html

$arg = get_class ( $arg ) . ‘ Object (‘ . implode ( ‘,’ , $args ). ‘)’ ;
>
>
?>

Источник

debug_backtrace

debug_backtrace() выводит стек вызовов функций PHP в массив.

Список параметров

В версии 5.3.6, этот аргумент является битовой маской для следующих настроек:

Настройки debug_backtrace()
DEBUG_BACKTRACE_PROVIDE_OBJECT Требуется или нет заполнять данные «объектов».
DEBUG_BACKTRACE_IGNORE_ARGS Требуется или нет не выводить данные с индексом «args», то есть списки аргументов всех функций/методов, для уменьшения расхода памяти.

До версии 5.3.6 принимаются только значения TRUE или FALSE , которые означают, задана настройка DEBUG_BACKTRACE_PROVIDE_OBJECT или нет соответственно.

В версии 5.4.0, этот аргумент используется для ограничения количества вызовов функций, которые будут выведены. По умолчанию ( limit =0) будет выведен весь стек вызовов.

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

Возвращает массив вложенных ассоциативных массивов ( array ). Описание элементов массива приведено ниже:

Список возможных значений элементов массивов, возвращаемых функцией debug_backtrace()

Имя Тип Описание
function string Имя текущей функции. См. также __FUNCTION__.
line integer Текущий номер строки. См. также __LINE__.
file string Имя текущего файла. См. также __FILE__.
class string Имя текущего класса. См. также __CLASS__
object object Текущий объект.
type string Текущий тип вызова функции. Если это вызов метода объекта, будет выведено «->». Если это вызов статического метода класса, то «::». Если это простой вызов функции, не выводится ничего.
args array При нахождении внутри функции, будет выведен список аргументов этой функции. Если внутри включаемого файла, будет выведен список включаемых файлов.

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

Версия Описание
5.4.0 Добавлен необязательный аргумент limit .
5.3.6 Аргумент provide_object заменен на options и добавлена дополнительная настройка DEBUG_BACKTRACE_IGNORE_ARGS .
5.2.5 Добавлен необязательный аргумент provide_object .
5.1.1 Элементом возвращаемого массива теперь может быть текущий объект object .

Примеры

Пример #1 Пример использования debug_backtrace()

function a_test ( $str )
echo «\nHi: $str » ;
var_dump ( debug_backtrace ());
>

a_test ( ‘friend’ );
?>

// filename: /tmp/b.php
include_once ‘/tmp/a.php’ ;
?>

Результат аналогичен приведенному ниже, если запустить /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() — Выводит стек вызовов функций

Источник

Оцените статью