note 94981 deleted from function.debug-backtrace by danbrown
| From: | danbrown@php.net | Date: | Mon, 07 Dec 2009 01:44:51 +0000 |
| Subject: | note 94981 deleted from function.debug-backtrace by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-163629@lists.php.net to get a copy of this message | ||
Note Submitter: strata_ranger at hotmail dot com
----
To clarify the documentation, when looking at a backtrace the 'class' and
'object' elements do not refer to the "current" class or object (i.e: $this or
self) relative to the given file and line number; they belong with the 'type' and
'function' elements and identify whether it was a global function or object/class method
being called. (This allows you to create a valid callback to that function should the need arise.)
If you want to know whether a class method was called from a private, protected, or public context,
look for the 'class' or 'object' elements from the next index up in your
backtrace (if present).
For example:
<?php
class Foo
{
static public function bar()
{
// Call bar2() below
self::bar2();
}
static public function bar2()
{
// Dump a backtrace
var_dump(debug_backtrace());
}
}
Foo::bar2();
//
// Array(1)
// {
// [0] => Array(...)
// {
// ['class'] => string(3) 'Foo'
// ['type'] => string(2) '::'
// ['function'] => string(3) 'bar2'
// }
// }
Foo::bar();
//
// Array(2)
// {
// [0] => Array(...)
// {
// ['class'] => string(3) 'Foo'
// ['type'] => string(2) '::'
// ['function'] => string(3) 'bar2'
// }
// [1] => Array(...)
// {
// ['class'] => string(3) 'Foo'
// ['type'] => string(2) '::'
// ['function'] => string(3) 'bar'
// }
// }
?>
Note in the first case, we called Foo::bar2() publically; in the second, Foo::bar2() was called from
within Foo::bar(). This is not directly mentioned in the backtrace (index 0 reads the same in
either case) but we can interpret it ourselves, because in the first case, Foo::bar2() is the start
and end of the backtrace whereas in the second case there is an additional element upstream that it
was called from.
Here is a simple wrapper for debug_backtrace() that creates two additional elements,
'this' and 'static', identifying the values of $this and self at the time where
a function was invoked, thus making it easier to determine whether a class method was called
publically, or privately from within its own class:
<?php
function this_debug_backtrace()
{
// Get the backtrace
$args = func_get_args();
$stack = call_user_func_array('debug_backtrace', $args);
// Pop the first two elements (call_user_func_array and this_debug_backtrace)
// from the backtrace. We're not interested in them
array_shift($stack);
array_shift($stack);
// Begin analyzing the backtrace now
foreach($stack as $cx => &$info)
{
if (isset($stack[$cx+1]))
{
// Add two more indexes: 'this' and 'self' identify the current
object/class
// relative to the file/line number where a function was invoked
$context = $stack[$cx+1];
if (isset($context['object'])) $info['this'] =
$context['object'];
if (isset($context['class'])) $info['self'] =
$context['class'];
}
} unset($info);
return $stack;
}