160

Is there a PHP function to find out the name of the caller function in a given function?

2
  • You should use Xdebug. See my answer in this post : stackoverflow.com/questions/1513069/… Commented Mar 29, 2012 at 22:48
  • 16
    Xdebug is categorically not just a PHP function, which was the original request. If you want to e.g. use the caller function name in later PHP logic and not install XDebug on production servers, you need a PHP function. Commented Jul 6, 2012 at 10:37

13 Answers 13

227

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']}";
Sign up to request clarification or add additional context in comments.

6 Comments

It seems to me that this prints the callee function name. Use list(, $caller) = debug_backtrace(false); to get caller, false for performance ;-) (php5.3)
Many solutions seen on the web get the second element of the backtrace array to get the instance caller: can we be so sure about it? Is the second element always the one we are searching for? I thought a __construct() which includes inside another call such as parent::__construct() could shift of another position the real caller (did not tried yet).
I tried checking the order of the callers returned while using a ReflectionClass, and it obviously changes the position of the "real" caller method, which is visible in the user interface, so no assumption on the backtrace position can be made.
array shift will remove first element and return the removed element. The original array will be modified and this should give the required result echo 'called by '.$trace[0]['function']
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function']; to get caller name with better performmance.
|
18

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

more info

Comments

17
echo debug_backtrace()[1]['function'];

Works since PHP 5.4.

Or optimised (e.g. for non-debug use cases):

echo debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'];

The first argument prevents to populate unused function arguments, the second limits the trace to two levels (we need the second).

Comments

16

This is very late but I would like to share the function that will give name of the function from which current function is called.

public function getCallingFunctionName($completeTrace=false)
    {
        $trace=debug_backtrace();
        if($completeTrace)
        {
            $str = '';
            foreach($trace as $caller)
            {
                $str .= " -- Called by {$caller['function']}";
                if (isset($caller['class']))
                    $str .= " From Class {$caller['class']}";
            }
        }
        else
        {
            $caller=$trace[2];
            $str = "Called by {$caller['function']}";
            if (isset($caller['class']))
                $str .= " From Class {$caller['class']}";
        }
        return $str;
    }

I hope this will be useful.

Comments

16

debug_backtrace() supplies details of parameters, function/method calls in the current call stack.

Comments

7

Made this and using this myself

/**
 * Gets the caller of the function where this function is called from
 * @param string what to return? (Leave empty to get all, or specify: "class", "function", "line", "class", etc.) - options see: http://php.net/manual/en/function.debug-backtrace.php
 */
function getCaller($what = NULL)
{
    $trace = debug_backtrace();
    $previousCall = $trace[2]; // 0 is this call, 1 is call in previous function, 2 is caller of that function

    if(isset($what))
    {
        return $previousCall[$what];
    }
    else
    {
        return $previousCall;
    }   
}

Comments

3

I just wanted to state that flori's way won't work as a function because it will always return the called function name instead of the caller, but I don't have reputation for commenting. I made a very simple function based on flori's answer that works fine for my case:

class basicFunctions{

    public function getCallerFunction(){
        return debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function'];
    }

}

EXAMPLE:

function a($authorisedFunctionsList = array("b")){
    $ref = new basicFunctions;
    $caller = $ref->getCallerFunction();

    if(in_array($caller,$authorisedFunctionsList)):
        echo "Welcome!";
        return true;
    else:
        echo "Unauthorised caller!";
        return false; 
    endif;
}

function b(){
    $executionContinues = $this->a();
    $executionContinues or exit;

    //Do something else..
}

Comments

2

You can extract this information from the array returned by debug_backtrace

Comments

2

This one worked best for me: var_dump(debug_backtrace());

Comments

1

Actually I think debug_print_backtrace() does what you need. http://php.net/manual/en/function.debug-print-backtrace.php

Comments

0

This should work:

$caller = next(debug_backtrace())['function'];

Comments

0

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()
**/```

Comments

0

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

Comments