Php print call stack on error

[php] Print PHP Call Stack

I’m looking for a way to print the call stack in PHP.

Bonus points if the function flushes the IO buffer.

The answer is

More readable than debug_backtrace() :

$e = new \Exception; var_dump($e->getTraceAsString()); #2 /usr/share/php/PHPUnit/Framework/TestCase.php(626): SeriesHelperTest->setUp() #3 /usr/share/php/PHPUnit/Framework/TestResult.php(666): PHPUnit_Framework_TestCase->runBare() #4 /usr/share/php/PHPUnit/Framework/TestCase.php(576): PHPUnit_Framework_TestResult->run(Object(SeriesHelperTest)) #5 /usr/share/php/PHPUnit/Framework/TestSuite.php(757): PHPUnit_Framework_TestCase->run(Object(PHPUnit_Framework_TestResult)) #6 /usr/share/php/PHPUnit/Framework/TestSuite.php(733): PHPUnit_Framework_TestSuite->runTest(Object(SeriesHelperTest), Object(PHPUnit_Framework_TestResult)) #7 /usr/share/php/PHPUnit/TextUI/TestRunner.php(305): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult), false, Array, Array, false) #8 /usr/share/php/PHPUnit/TextUI/Command.php(188): PHPUnit_TextUI_TestRunner->doRun(Object(PHPUnit_Framework_TestSuite), Array) #9 /usr/share/php/PHPUnit/TextUI/Command.php(129): PHPUnit_TextUI_Command->run(Array, true) #10 /usr/bin/phpunit(53): PHPUnit_TextUI_Command::main() #11 " 
$e = new Exception; error_log(var_export($e->getTraceAsString(), true)); 

Strange that noone posted this way:

debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); 

This actually prints backtrace without the garbage — just what method was called and where.

Backtrace dumps a whole lot of garbage that you don’t need. It takes is very long, difficult to read. All you usuall ever want is «what called what from where?» Here is a simple static function solution. I usually put it in a class called ‘debug’, which contains all of my debugging utility functions.

debugUtils::callStack(debug_backtrace()); 

And it produces output like this:

================================================== 1. DatabaseDriver.php::getSequenceTable(169) 2. ClassMetadataFactory.php::loadMetadataForClass(284) 3. ClassMetadataFactory.php::loadMetadata(177) 4. ClassMetadataFactory.php::getMetadataFor(124) 5. Import.php::getAllMetadata(188) 6. Command.php::execute(187) 7. Application.php::run(194) 8. Application.php::doRun(118) 9. doctrine.php::run(99) 10. doctrine::include(4) ================================================== 

If you want a stack trace which looks very similar to how php formats the exception stack trace than use this function I wrote:

function debug_backtrace_string() < $stack = ''; $i = 1; $trace = debug_backtrace(); unset($trace[0]); //Remove call to this function from stack trace foreach($trace as $node) < $stack .= "#$i ".$node['file'] ."(" .$node['line']."): "; if(isset($node['class'])) < $stack .= $node['class'] . "->"; > $stack .= $node['function'] . "()" . PHP_EOL; $i++; > return $stack; > 

This will return a stack trace formatted like this:

#1 C:\Inetpub\sitename.com\modules\sponsors\class.php(306): filePathCombine() #2 C:\Inetpub\sitename.com\modules\sponsors\class.php(294): Process->_deleteImageFile() #3 C:\Inetpub\sitename.com\VPanel\modules\sponsors\class.php(70): Process->_deleteImage() #4 C:\Inetpub\sitename.com\modules\sponsors\process.php(24): Process->_delete() 

Does that do what you want?

See debug_print_backtrace . I guess you can call flush afterwards if you want.

phptrace is a great tool to print PHP stack anytime when you want without installing any extensions.

There are two major function of phptrace: first, print call stack of PHP which need not install anything, second, trace php execution flows which needs to install the extension it supplies.

$ ./phptrace -p 3130 -s # phptrace -p -s phptrace 0.2.0 release candidate, published by infra webcore team process = /home/xxx/opt/nginx/webapp/block.php [0x7f27b9a99dc8] sleep /home/xxx/opt/nginx/webapp/block.php:6 [0x7f27b9a99d08] say /home/xxx/opt/nginx/webapp/block.php:3 [0x7f27b9a99c50] run /home/xxx/opt/nginx/webapp/block.php:10 

Use debug_backtrace to get a backtrace of what functions and methods had been called and what files had been included that led to the point where debug_backtrace has been called.

please take a look at this utils class, may be helpful:

Источник

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.

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

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

Источник

Читайте также:  Си шарп windows forms
Оцените статью