获取PHP中调用方函数的名称?


135

是否有PHP函数可以找出给定函数中调用者函数的名称?


您应该使用Xdebug。见这个职位我的回答: stackoverflow.com/questions/1513069/...
svassr

13
Xdebug绝对不是最初的请求就是PHP函数。如果要在更高版本的PHP逻辑中使用调用方函数名称,而不是在生产服务器上安装XDebug,则需要一个PHP函数。
JP

Answers:


198

请参见debug_backtrace-这可以一直跟踪您的调用堆栈。

拨打电话的方法如下:

$trace = debug_backtrace();
$caller = $trace[1];

echo "Called by {$caller['function']}";
if (isset($caller['class']))
    echo " in {$caller['class']}";

59
在我看来,这将打印被调用者函数的名称。使用list(, $caller) = debug_backtrace(false);让呼叫者,false性能;-)(PHP5.3)
Znarkus

在网络上看到的许多解决方案都使用backtrace数组的第二个元素来获取实例调用者:我们可以确定吗?第二个元素是否总是我们要寻找的元素?我以为__construct()包括在另一个调用中,例如parent :: __ construct()可以将实际调用者的另一个位置转移(尚未尝试)。
Emanuele Del Grande

1
我尝试检查使用ReflectionClass时返回的调用者的顺序,这显然更改了“真实”调用者方法的位置,该方法在用户界面中可见,因此无法对回溯位置进行任何假设。
Emanuele Del Grande

4
数组移位将删除第一个元素并返回删除的元素。原始数组将被修改,这将提供所需的结果echo 'called by '.$trace[0]['function']
GoodSp33d 2012年

21
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'];以获得更好的呼叫者姓名。
ahuigo 2015年

17

Xdebug提供了一些不错的功能。

<?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();
?>

将返回跟踪

callee() called @ /var/www/xd.php: 16 from MyClass::__construct

在Ubuntu上安装Xdebug的最佳方法是

sudo aptitude install php5-xdebug

您可能需要先安装php5-dev

sudo aptitude install php5-dev

更多信息


15

这已经很晚了,但是我想分享该函数,该函数将给出从中调用当前函数的函数的名称。

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;
    }

我希望这会有所帮助。


1
不客气,大卫!我也在项目
中将其

“完整跟踪”模式非常有用。感谢分享。
Leopoldo Sanczyk


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

PHP 5.4开始工作

或经过优化(例如,用于非调试用例):

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

第一个参数防止填充未使用的函数参数,第二个参数将跟踪限制为两个级别(我们需要第二个级别)。


7

做这个并自己使用

/**
 * 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;
    }   
}

3

我只是想说明flori的方式不能用作函数,因为它将始终返回被调用的函数名而不是调用者,但是我没有发表评论的声誉。我根据flori的答案做了一个非常简单的函数,适合我的情况:

class basicFunctions{

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

}

例:

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..
}




1

这应该工作:

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

0

这样可以很好地做到:


// 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()
**/```
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.