php get stack trace
(PHP 4 >= 4.3.0, PHP 5, PHP 7)
debug_backtrace — Выводит стек вызовов функций в массив
Описание
debug_backtrace() выводит стек вызовов функций PHP в массив.
Список параметров
В версии 5.4.0, этот аргумент используется для ограничения количества вызовов функций, которые будут выведены. По умолчанию ( limit =0) будет выведен весь стек вызовов.
Возвращаемые значения
Возвращает массив вложенных ассоциативных массивов ( array ). Описание элементов массива приведено ниже:
Имя | Тип | Описание |
---|---|---|
function | string | Имя текущей функции. См. также __FUNCTION__. |
line | integer | Текущий номер строки. См. также __LINE__. |
file | string | Имя текущего файла. См. также __FILE__. |
class | string | Имя текущего класса. См. также __CLASS__ |
object | object | Текущий объект. |
type | string | Текущий тип вызова функции. Если это вызов метода объекта, будет выведено «->». Если это вызов статического метода класса, то «::». Если это простой вызов функции, не выводится ничего. |
args | array | При нахождении внутри функции, будет выведен список аргументов этой функции. Если внутри включаемого файла, будет выведен список включаемых файлов. |
Список изменений
Примеры
Пример #1 Пример использования debug_backtrace()
a_test ( ‘friend’ );
?>
// filename: /tmp/b.php
include_once ‘/tmp/a.php’ ;
?>
Результат аналогичен приведенному ниже, если запустить /tmp/b.php :
Смотрите также
debug_print_backtrace
debug_print_backtrace — Выводит стек вызовов функций
Описание
debug_print_backtrace() выводит стек вызовов функций. Выводит вызовы функций, имена включённых/требуемых файлов и другую информацию из функций ( eval() ).
Список параметров
Аргумент является битовой маской для следующих настроек:
DEBUG_BACKTRACE_IGNORE_ARGS | Нужно ли исключить ключ «args», то есть списки аргументов всех функций/методов, чтобы уменьшить расход памяти. |
Аргумент используется для ограничения количества вызовов функций, которые будут выведены. По умолчанию ( limit = 0 ) будет выведен весь стек вызовов.
Возвращаемые значения
Функция не возвращает значения после выполнения.
Примеры
Пример #1 Пример использования debug_print_backtrace()
function c () <
debug_print_backtrace ();
>
Результатом выполнения данного примера будет что-то подобное:
Смотрите также
User Contributed Notes 5 notes
Another way to manipulate and print a backtrace, without using output buffering:
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 ();
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»);
This code will give you a simple horizontal stack trace to assist debugging:
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.
Exception::getTrace
Exception::getTrace — Gets the stack trace
Description
Returns the Exception stack trace.
Parameters
This function has no parameters.
Return Values
Examples
Example #1 Exception::getTrace() example
function test () <
throw new Exception ;
>
The above example will output something similar to:
See Also
User Contributed Notes 5 notes
Two important points about this function which are not documented:
1) The trace does not include the file / line at which the exception is thrown; that entry is only recorded in the top-level getFile/Line methods.
2) Elements are returned in ‘closest-first’ order, e.g. if you have a script x which calls function y which calls function z which throws an exception, then the first trace element will be ‘Y’ and the second will be ‘X’.
If you are wanting to see the args within a stack trace on PHP 7.4, note that there is now a zend flag in the php.ini file that is default set to Off.
Set this flag to On and it will show the args again.
When calling getTrace(), there is also the name of the class in returned array:
throw new Exception ( ‘FATAL ERROR: bla bla. ‘ );
>
?>
Will show something like:
array(1) <
[0]=> array(6) <
[«file»]=> string(54) «/. /test.php»
[«line»]=> int(37)
[«function»]=> string(11) «__construct»
[«class»]=> string(4) «Test»
[«type»]=> string(2) «->»
[«args»]=> array(0) < >
>
>
You can use this function to format a exception:
Exception: «FATAL ERROR: bla bla. » @ Test->__construct();
debug_backtrace
(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)
debug_backtrace — Выводит стек вызовов функций в массив
Описание
debug_backtrace() выводит стек вызовов функций PHP в массив.
Список параметров
Аргумент является битовой маской для следующих настроек:
DEBUG_BACKTRACE_PROVIDE_OBJECT | Нужно ли заполнять данные для ключа object. |
DEBUG_BACKTRACE_IGNORE_ARGS | Нужно ли исключить аргументы всех функций/методов в ключе «args» для уменьшения расхода памяти. |
Аргумент используется для ограничения количества вызовов функций, которые будут выведены. По умолчанию ( limit = 0 ) будет выведен весь стек вызовов.
Возвращаемые значения
Возвращает массив вложенных ассоциативных массивов ( array ). Описание элементов массива приведено ниже:
Имя | Тип | Описание |
---|---|---|
function | string | Имя текущей функции. Смотрите также __FUNCTION__. |
line | int | Текущий номер строки. Смотрите также __LINE__. |
file | string | Имя текущего файла. Смотрите также __FILE__. |
class | string | Имя текущего класса. Смотрите также __CLASS__ |
object | object | Текущий объект. |
type | string | Текущий тип вызова функции. Если это вызов метода объекта, будет выведено «->». Если это вызов статического метода класса, то «::». Если это простой вызов функции, не выводится ничего. |
args | array | При нахождении внутри функции, будет выведен список аргументов этой функции. Если внутри включаемого файла, будет выведен список включаемых файлов. |
Примеры
Пример #1 Пример использования debug_backtrace()
a_test ( ‘друг’ );
?>
// файл /tmp/b.php
include_once ‘/tmp/a.php’ ;
?>
Результат аналогичен приведённому ниже, если запустить /tmp/b.php :
Смотрите также
User Contributed Notes 36 notes
Here’s a function I just wrote for getting a nice and comprehensible call trace. It is probably more resource-intensive than some other alternatives but it is short, understandable, and gives nice output (Exception->getTraceAsString()).
$test = new ParentClass ();
?>
Output:
array(1) <
[0]=>
array(7) <
[«file»]=>
string(23) «/home/jcm/testdebug.php»
[«line»]=>
int(18)
[«function»]=>
string(11) «__construct»
[«class»]=>
string(11) «ParentClass»
[«object»]=>
object(ParentClass)#1 (1) <
[«_child»]=>
object(ChildClass)#2 (1) <
[«_parent»]=>
*RECURSION*
>
>
[«type»]=>
string(2) «->»
[«args»]=>
array(0) <
>
>
>
Attention in the *RECURSION* hint provided
Just a short note on debug_backtrace options for PHP 5.3.6 or newer:
use this example and try calling debug_backtrace with different options
function F1 ()
<
echo «
» ;
echo «in F1 now» ;
echo «» ;
>
class DebugOptionsTest
<
function F2 ()
<
echo «
» ;
echo «in F2 now» ;
F1 ();
>
echo » calling F1″ ;
F1 ();
Simple function to get a string in form «filename: [class->][function(): ]»
Quick and dirty formatted output from debug_backtrace.
When using debug_backtrace() to check if you’re being accessed from another caller, please remember to ask debug_backtrace to only go as far as needed in depth and skip taking the entire debug object as return parameter:
I use this simple but effective function so i can see which method in the child class called the current method (in the parent class).
function get_caller_method ()
<
$traces = debug_backtrace ();
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
*/
A usual entry looks like this:
array( 6 ) <
‘file’ =>
string ( 87 ) «DbSelector.php»
‘line’ =>
int ( 171 )
‘function’ =>
string ( 5 ) «error»
‘class’ =>
string ( 42 ) «LoggingService»
‘type’ =>
string ( 2 ) «::»
‘args’ =>
array( 1 ) <
[ 0 ] =>
string ( 27 ) «Connecting to DB: unittests»
>
>
?>
Be warned though that ‘file’ and ‘class’ do not reference the same thing!
‘file’ means which file calls the next step.
‘class’ is the next step being called.
So ‘file’ is the caller, ‘class’ is the callee.
It works a little bit different with resources in different PHP versions.
For example:
function foo($bar)
<
return debug_backtrace();
>
With 5.3.10 I got:
when resource is opened: resource
when resource is closed: resource
With 5.5.9:
when resource is opened: resource
when resource is closed: unknown type
Here is a function to cleanly output the debug_backtrace to the error_log
PHP Stack Trace: Understanding It and Using It to Debug
If you’ve spent any amount of time writing code, you’ll know that debugging is a vital part of the process. Sometimes it can be challenging to work out why your program has crashed or stopped working. It can be frustrating to encounter an error that doesn’t seem to make sense.
Knowing this, it’s wise to expand the tools in your debugging toolbox. When you add new tools and review well-used ones, you can make debugging quicker and more satisfying.
This article is about one such tool: the stack trace.
What Is a Stack Trace?
I imagine you’ve seen a stack trace before. At first, it can look like an impenetrable block of jargon and code. It might resemble a list of statements, each seeming more meaningless than the last. Each point on the list may refer to a file you may never have known existed. In reality, this is the PHP interpreter trying to communicate what has gone wrong and help you fix it. It’s possible to understand this text and use it to make your programs better.
When your program is running, the PHP interpreter keeps track of which function is currently running. Not only that, but the interpreter also keeps track of which function called the current function, and so on, all the way down to the entry function of the program.
The interpreter does this using a data type called a stack. You can imagine it as a stack of cards. A card either goes on top or gets taken from the top.
For our case, we’re interested in the call stack. As your program calls a function, that function goes the top of the call stack. When the function returns, your program removes it from the top of that stack. So the stack trace is a list of the functions in the call stack at the point an exception is triggered.
Throwing an exception is how the interpreter tells you an error has happened. This could be from a mistyped variable, incorrect input, or any type of exception that you’ve defined in your code.
What Does the Stack Trace Look Like?
I’m going to use a simple procedural example to generate my stack trace. Traces from frameworks and your own more developed applications are likely to be longer. However, looking at the simplest version helps you understand more complex, real-world examples.
I spent over a decade teaching secondary mathematics, so I can see this is going to cause a problem. Running the program gives me the following stack trace:
The trace starts with a PHP warning, which tries to explain what the problem is and where it happens. In my case, a “division by zero” error happened in line 6.
It’s important to read the stack trace in reverse order—in other words, from the bottom up. My stack has only two items. The function running at the point the program threw an exception is at the bottom. This is my helpfully named divide_by_zero function. Reading up a level, you can see the function called this function, and the function is the entry to the program. The number after the colon is the line number that the interpreter thinks the error has happened in. (Pro tip: Sometimes it’s useful to look one line back and make sure there’s a semicolon ending that line.)
Having the full trace is important. You can follow it like breadcrumbs back through your program. Your function may fail under certain circumstances only. Maybe it works most of the time, but when called in a particular chain, it fails. Seeing the chain of events that led to the error can help you unpick the problem.
How Does the Stack Trace Help With Debugging?
With the stack trace, it’s possible to work out the entire chain of events that led to the exception being thrown. Now that you know where the error has happened, you can add some logging. The error is happening on this line, so what’s the state of the program just before this? If your application is in production, you can export these logs to a service like Scalyr. Scalyr can aggregate these logs for you and allow you to get an overview of how often the error is happening.
Just as important: How about adding some logging in the functions further up the call stack? You now know every function involved in creating this particular error. With this information, you can run experiments and test ideas with more precision. There’s a helpful datasheet here to help think about how to manage your logs as the amount of data you collect increases.
Xdebug and IDE Integration
Xdebug is a popular tool that gives you more insight into what is happening while your code executes. It’s a PHP extension that lends a helping hand when you’re debugging your applications. This tool allows you to interact directly with running PHP scripts, allowing you to step through the program and observe what’s happening. With Xdebug, you can deal with problems that are complex and nuanced without relying solely on log statements. When integrated with your IDE, Xdebug allows your debugging to go up another level. You can integrate this tool with most code editors, including VSCode and even VIM.
With Xdebug set up and configured, you can set a breakpoint on the line where there’s an exception or error. Doing this allows you to interrupt the program and investigate. You’ll be able to see the live call stack and the variables currently in memory. You can execute commands and test ideas while the program is live. This is a powerful debugging technique.
Stack Trace Without Errors
With Xdebug, you can generate a stack trace at any point in your program. Maybe the program isn’t throwing an error, but it doesn’t seem to be working as you expected it to. Or, as mentioned earlier, you could have a function that works in certain circumstances but not in others.
Xdebug provides a set of debugging functions that you can put to good use. This one is the most useful for our needs:
Adding the command above will print the call stack, along with your message, without interrupting the program. You could add this to your temperamental function, allowing you to see the call stack—when it succeeds and when it fails. Combining these sets of information can help you identify issues more quickly.
You can read more about the other debugging functions that Xdebug provides in the documentation.
However, this kind of command in production can either confuse a user or give someone with malicious intent too much information. For this reason, it makes sense to ensure your production environment has display_errors set to Off in the live php.ini file.
Conclusion
I hope this brief article allows you to understand the stack trace and think a bit more about how you might use it. As I’ve mentioned, it’s a really helpful tool and can help you identify and solve errors quickly.
In local development, tools like Xdebug allow your debugging efforts to be truly effective. In your production environment, using logging and log aggregation can allow you to succeed there as well.
If you’re just getting started in collecting stack traces and logs, check out this workshop!
This post was written by Kevin Cunningham. Kevin is a full-stack developer working with PHP and Python on the backend and Vanilla JS and Vue on the front end. He loves taking ideas and making something tangible from them that adds value to businesses and lives. He spent 12 years teaching high school mathematics and still loves doing puzzles when he’s not hanging out with his wife and sons on the beach in Brighton, England.