Php debug print backtrace

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

I keep seeing qualification lists for error types/error-nums as arrays; In user notes and in the manual itself. For example, in this manual entry’s example, when trying to seperate behavior for the variable trace in the error report:

// set of errors for which a var trace will be saved
$user_errors = array( E_USER_ERROR , E_USER_WARNING , E_USER_NOTICE );

if ( in_array ( $errno , $user_errors )) //. whatever
>

//. ?>

I was under the impression that PHP error code values where bitwise flag values. Wouldn’t bitwise masking be better? So I propose a slightly better way:

$user_errors = E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE ;

if ( $errno & $user_errors ) //. whatever
>

//. ?>
Or for those of you who don’t like the idea of using an integer as the condition in an if statement:

if (( $errno & $user_errors ) > 0 ) //. whatever
>
?>

I think that’s much more efficient than using _yet another_ array() constuct and an in_array().

If I am wrong, and the E_* constants aren’t supposed to be used in this fashion (ie, the constans aren’t guaranteed to be bitwise, which would be odd since that’s how they’re setup in the php.ini file), then delete me. I just don’t see why one should be using arrays when bitwise comparisons will work, considering the bitwise method should be MUCH more efficient.

Although the root user writes to the files ‘error_log’ and ‘access_log’, the Apache user has to own the file referenced by ‘error_log = filename’ or no log entries will be written.

; From php.ini
; Log errors to specified file.
error_log = /usr/local/apache/logs/php.errors

[root@www logs]$ ls -l /usr/local/apache/logs/php.errors
-rw-r—r— 1 nobody root 27K Jan 27 16:58 php.errors

PHP5 only (only tested with php5.0).

If you, for some reason, prefer exceptions over errors and have your custom error handler (set_error_handler) wrap the error into an exception you have to be careful with your script.

Because if you, instead of just calling the exception handler, throws the exception, and having a custom exception handler (set_exception_handler). And an error is being triggered inside that exception handler, you will get a weird error:
«Fatal error: Exception thrown without a stack frame in Unknown on line 0»

This error is not particulary informative, is it? 🙂

This example below will cause this error.
class PHPErrorException extends Exception
private $context = null ;
public function __construct
( $code , $message , $file , $line , $context = null )
parent :: __construct ( $message , $code );
$this -> file = $file ;
$this -> line = $line ;
$this -> context = $context ;
>
>;

function error_handler ( $code , $message , $file , $line ) throw new PHPErrorException ( $code , $message , $file , $line );
>

function exception_handler ( Exception $e )
<
$errors = array(
E_USER_ERROR => «User Error» ,
E_USER_WARNING => «User Warning» ,
E_USER_NOTICE => «User Notice» ,
);

echo $errors [ $e -> getCode ()]. ‘: ‘ . $e -> getMessage (). ‘ in ‘ . $e -> getFile ().
‘ on line ‘ . $e -> getLine (). «\n» ;
echo $e -> getTraceAsString ();
>

set_error_handler ( ‘error_handler’ );
set_exception_handler ( ‘exception_handler’ );

// Throw exception with an /unkown/ error code.
throw new Exception ( ‘foo’ , 0 );
?>

There are however, easy fix for this as it’s only cause is sloppy code.
Like one, directly call exception_handler from error_handler instead of throwing an exception. Not only does it remedy this problem, but it’s also faster. Though this will cause a `regular` unhandled exception being printed and if only «designed» error messages are intended, this is not the ultimate solution.

So, what is there to do? Make sure the code in exception_handlers doesn’t cause any errors! In this case a simple isset() would have solved it.

If you are using PHP as an Apache module, your default behavior may be to write PHP error messages to Apache’s error log. This is because the error_log .ini directive may be set equal to «error_log» which is also the name of Apache’s error log. I think this is intentional.

However, you can separate Apache errors from PHP errors if you wish by simply setting a different value for error_log. I write mine in the /var/log folder.

Note the example code listed here calls date() every time this is called. If you have a complex source base which calls the custom error handler often, it can end up taking quite a bit of time. I ran a profiler on som code and discovered that 50% of the time was spent in the date function in this error handler.

When configuring your error log file in php.ini, you can use an absolute path or a relative path. A relative path will be resolved based on the location of the generating script, and you’ll get a log file in each directory you have scripts in. If you want all your error messages to go to the same file, use an absolute path to the file.

In some application development methodologies, there is the concept of an application root directory, indicated by «/» (even on Windows). However, PHP does not seem to have this concept, and using a «/» as the initial character in a log file path produces weird behavior on Windows.

If you are running on Windows and have set, in php.ini:

You will get some, but not all, error messages. The file will appear at

and contain internally generated error messages, making it appear that error logging is working. However, log messages requested by error_log() do NOT appear here, or anywhere else, making it appear that the code containing them did not get processed.

Apparently on Windows the internally generated errors will interpret «/» as «C:\» (or possibly a different drive if you have Windows installed elsewhere — I haven’t tested this). However, the error_log process apparently can’t find «/» — understandably enough — and the message is dropped silently.

It is totally possible to use debug_backtrace() inside an error handling function. Here, take a look:

function errorHandler ( $errno , $errstr , $errfile , $errline , $errcontext )
echo ‘Into ‘ . __FUNCTION__ . ‘() at line ‘ . __LINE__ .
«\n\n—ERRNO—\n» . print_r ( $errno , true ).
«\n\n—ERRSTR—\n» . print_r ( $errstr , true ).
«\n\n—ERRFILE—\n» . print_r ( $errfile , true ).
«\n\n—ERRLINE—\n» . print_r ( $errline , true ).
«\n\n—ERRCONTEXT—\n» . print_r ( $errcontext , true ).
«\n\nBacktrace of errorHandler()\n» .
print_r ( debug_backtrace (), true );
>

function a ( )
//echo «a()’s backtrace\n».print_r( debug_backtrace(), true);
asdfasdf ; // oops
>

function b ()
//echo «b()’s backtrace\n».print_r( debug_backtrace(), true);
a ();
>

Into errorhandler() at line 9

—ERRSTR—
Use of undefined constant asdfasdf — assumed ‘asdfasdf’

Backtrace of errorHandler()
Array
(
[0] => Array
(
[function] => errorhandler
[args] => Array
(
[0] => 8
[1] => Use of undefined constant asdfasdf — assumed ‘asdfasdf’
[2] => /home/theotek/test-1.php
[3] => 23
[4] => Array
(
)

[1] => Array
(
[file] => /home/theotek/test-1.php
[line] => 23
[function] => a
) [2] => Array
(
[file] => /home/theotek/test-1.php
[line] => 30
[function] => a
[args] => Array
(
) [3] => Array
(
[file] => /home/theotek/test-1.php
[line] => 33
[function] => b
[args] => Array
(
)

So, the first member of the backtrace’s array is not really surprising, except from the missing «file» and «line» members.

The second member of the backtrace seem the be a hook inside the zend engine that is used to trigger the error.

Other members are the normal backtrace.

Источник

debug_print_backtrace

debug_print_backtrace() выводит стек вызовов функций. Выводит вызовы функций, имена включённых/требуемых файлов и другую информацию из функций ( eval() ).

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

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

Опции debug_print_backtrace()
DEBUG_BACKTRACE_IGNORE_ARGS Нужно ли исключить ключ «args», то есть списки аргументов всех функций/методов, чтобы уменьшить расход памяти.

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

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

Функция не возвращает значения после выполнения.

Примеры

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

function c () debug_print_backtrace ();
>

Результатом выполнения данного примера будет что-то подобное:

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

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

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

Источник

PHP debug_print_backtrace() Function

The debug_print_backtrace() function prints a PHP backtrace.

This function displays data from the code that led up to the debug_print_backtrace() function.

Syntax

Parameter Values

Parameter Description
options Optional. Specifies a bitmask for the following option: DEBUG_BACKTRACE_IGNORE_ARGS (Whether or not to omit the «args» index, and all the function/method arguments, to save memory)
limit Optional. Limits the number of stack frames printed. By default (limit=0) it prints all stack frames

Technical Details

Return Value: None
PHP Version: 5.0+
PHP Changelog: PHP 5.4: The optional parameter limit was added
PHP 5.3.6: The optional parameter options was added

PHP Error Reference

Unlock Full Access 50% off

COLOR PICKER

colorpicker

Join our Bootcamp!

Report Error

If you want to report an error, or if you want to make a suggestion, do not hesitate to send us an e-mail:

Thank You For Helping Us!

Your message has been sent to W3Schools.

Top Tutorials
Top References
Top Examples
Get Certified

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Источник

Читайте также:  Tag cloud with php
Оцените статью