Is there a PHP function to find out the name of the caller function in a given function?
Is there a PHP function to find out the name of the caller function in a given function?
See debug_backtrace - this can trace your call stack all the way to the top.
Here's how you'd get your caller:
$trace = debug_backtrace();
$caller = $trace[1];
echo "Called by {$caller['function']}";
if (isset($caller['class']))
echo " in {$caller['class']}";
Xdebug provides some nice functions.
<?php
Class MyClass
{
function __construct(){
$this->callee();
}
function callee() {
echo sprintf("callee() called @ %s: %s from %s::%s",
xdebug_call_file(),
xdebug_call_line(),
xdebug_call_class(),
xdebug_call_function()
);
}
}
$rollDebug = new MyClass();
?>
will return trace
callee() called @ /var/www/xd.php: 16 from MyClass::__construct
To install Xdebug on ubuntu the best way is
sudo aptitude install php5-xdebug
You might need to install php5-dev first
sudo aptitude install php5-dev
This will do it nicely:
// Outputs an easy to read call trace
// Credit: https://www.php.net/manual/en/function.debug-backtrace.php#112238
// Gist: https://gist.github.com/UVLabs/692e542d3b53e079d36bc53b4ea20a4b
Class MyClass{
public function generateCallTrace()
{
$e = new Exception();
$trace = explode("\n", $e->getTraceAsString());
// reverse array to make steps line up chronologically
$trace = array_reverse($trace);
array_shift($trace); // remove {main}
array_pop($trace); // remove call to this method
$length = count($trace);
$result = array();
for ($i = 0; $i < $length; $i++)
{
$result[] = ($i + 1) . ')' . substr($trace[$i], strpos($trace[$i], ' ')); // replace '#someNum' with '$i)', set the right ordering
}
return "\t" . implode("\n\t", $result);
}
}
// call function where needed to output call trace
/**
Example output:
1) /var/www/test/test.php(15): SomeClass->__construct()
2) /var/www/test/SomeClass.class.php(36): SomeClass->callSomething()
**/```
I created a generic class, which can be helpful to many people who want to see the caller method's trace in a user-readable way. As in one of my projects we needed such information to be logged.
use ReflectionClass;
class DebugUtils
{
/**
* Generates debug traces in user readable form
*
* @param integer $steps
* @param boolean $skipFirstEntry
* @param boolean $withoutNamespaces
* @return string
*/
public static function getReadableBackTracke(
$steps = 4,
$skipFirstEntry = true,
$withoutNamespaces = true
) {
$str = '';
try {
$backtrace = debug_backtrace(false, $steps);
// Removing first array entry
// to make sure getReadableBackTracke() method doesn't gets displayed
if ($skipFirstEntry)
array_shift($backtrace);
// Reserved, so it gets displayed in calling order
$backtrace = array_reverse($backtrace);
foreach ($backtrace as $caller) {
if ($str) {
$str .= ' --> ';
}
if (isset($caller['class'])) {
$class = $caller['class'];
if ($withoutNamespaces) {
$class = (new ReflectionClass($class))->getShortName();
}
$str .= $class . $caller['type'];
}
$str .= $caller['function'];
}
} catch (\Throwable $th) {
return null;
}
return $str;
}
}
Usage: DebugUtils::getReadableBackTracke()
Sample output:
SomeClass->method1 --> SomeOtherClass->method2 --> TargetClass->targetMethod
Do good and keep helping others, happy coding :)