如何在PHP中获取调用函数/方法的名称?

Daw*_*hia 205 php

我知道函数debug_backtrace,但我正在寻找一些准备使用的函数实现GetCallingMethodName()吗?如果它也给了方法的类(如果它确实是一个方法),那将是完美的.

diy*_*ism 473

最简单的方法是:

echo debug_backtrace()[1]['function'];
Run Code Online (Sandbox Code Playgroud)

  • 为什么这没有被标记为正确的答案? (19认同)
  • 从5.4开始,您可以传递[第二个参数来限制条目数](http://br2.php.net/manual/en/function.debug-backtrace.php#refsect1-function.debug-backtrace-parameters). (9认同)
  • 值得优化一下:`debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,2)[1] ['function']` (8认同)
  • 如果您的浏览器崩溃尝试打印`debug_backtrace()`,您可能还有其他更严重的问题.您要么将*huge*对象作为参数传递,要么您的调用堆栈非常深,或者您正在使用非常狡猾的浏览器! (5认同)
  • 刚发现这个。非常有用,但值得注意的是,这里可能涉及大量开销。我运行了`print_r(debug_backtrace())`,它基本上使我的浏览器崩溃了,它返回的信息很重。 (2认同)

Ali*_*xel 139

debug_backtrace()函数是了解这一点的唯一方法,如果你是懒惰的,那么你应该GetCallingMethodName()自己编写代码的另一个原因.战斗懒惰!:d

  • 谁需要谷歌,同时拥有如此优秀的"编程答案搜索引擎"作为像你这样的stackoverflow用户:} http://stackoverflow.com/questions/190421/caller-function-in-php-5/190426#190426现在认真,谢谢! (22认同)
  • "打败懒惰!:D"但懒惰是一件好事:http://www.codinghorror.com/blog/archives/000237.html:}所以如果有人写了这样的功能,我真的很感激...... :} (20认同)
  • 为了更好的性能,请传递这些参数,`debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,2)`. (4认同)
  • 这与懒惰无关 - 如果程序员为解决方案付费,那么尝试不重新发明轮子是完全有效的。 (3认同)

小智 41

从PHP 5.4开始,你可以使用

        $dbt=debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,2);
        $caller = isset($dbt[1]['function']) ? $dbt[1]['function'] : null;
Run Code Online (Sandbox Code Playgroud)

这不会浪费内存,因为它忽略了参数并仅返回最后2个回溯堆栈条目,并且不会在此处生成通知作为其他答案.

  • 从 PHP 7 开始,第二行可以是 `$caller = $dbt[1]['function'] ?? 空;` (5认同)
  • @Krzysztof Trzos尝试`echo $ caller;`并且应该工作.;-) (2认同)
  • 这应该是公认的答案。 (2认同)

Luc*_*cia 26

您还可以使用php异常提供的信息,这是一个优雅的解决方案:


function GetCallingMethodName(){
    $e = new Exception();
    $trace = $e->getTrace();
    //position 0 would be the line that called this function so we ignore it
    $last_call = $trace[1];
    print_r($last_call);
}

function firstCall($a, $b){
    theCall($a, $b);
}

function theCall($a, $b){
    GetCallingMethodName();
}

firstCall('lucia', 'php');

你得到这个......(瞧!)

Array
(
    [file] => /home/lufigueroa/Desktop/test.php
    [line] => 12
    [function] => theCall
    [args] => Array
        (
            [0] => lucia
            [1] => php
        )

)

  • 有趣的方法和我有点喜欢它,但为什么它比使用debug_backtrace更好? (2认同)
  • 请注意,我做了一个快速的基准测试,看起来这个解决方案比debug_backtrace()慢2倍.但是,我们正在谈论微优化,直到您在代码中经常不使用此方法 (2认同)

gav*_*non 18

我最喜欢的方式,在一条线!

debug_backtrace()[1]['function'];
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

echo 'The calling function: ' . debug_backtrace()[1]['function'];
Run Code Online (Sandbox Code Playgroud)

请注意,这仅与去年发布的PHP版本兼容.但出于安全考虑,最好还是保持PHP最新状态.

  • @gavanon该评论表明缺乏对如何维护PHP和最流行工具的理解.在PHP 5.4发布之后,PHP 5.3继续接收*年*的安全问题更新.仅仅是旧版本的PHP并不意味着你必须使用*不安全的PHP. (3认同)
  • 大声笑谢谢@ialarmedalien:D至于兼容性,我也许对更新太过激进了?我觉得人们应该(合理地)更新他们的PHP。它是免费的,使用过时的软件也有安全风险。当您使用2或3年的PHP版本时,您不仅会迷失诸如此类的出色功能,还会使服务器面临风险。 (2认同)

Ani*_*nil 17

对我来说debug_backtrace是达到我的内存限制,我想在生产中使用它来记录和发送错误.

相反,我发现这个解决方案非常出色!

// Make a new exception at the point you want to trace, and trace it!
$e = new Exception;
var_dump($e->getTraceAsString());

// Outputs the following 
#2 /usr/share/php/PHPUnit/Framework/TestCase.php(626): SeriesHelperTest->setUp()
#3 /usr/share/php/PHPUnit/Framework/TestResult.php(666): PHPUnit_Framework_TestCase->runBare()
#4 /usr/share/php/PHPUnit/Framework/TestCase.php(576): PHPUnit_Framework_TestResult->run(Object(SeriesHelperTest))
#5 /usr/share/php/PHPUnit/Framework/TestSuite.php(757): PHPUnit_Framework_TestCase->run(Object(PHPUnit_Framework_TestResult))
#6 /usr/share/php/PHPUnit/Framework/TestSuite.php(733): PHPUnit_Framework_TestSuite->runTest(Object(SeriesHelperTest), Object(PHPUnit_Framework_TestResult))
#7 /usr/share/php/PHPUnit/TextUI/TestRunner.php(305): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult), false, Array, Array, false)
#8 /usr/share/php/PHPUnit/TextUI/Command.php(188): PHPUnit_TextUI_TestRunner->doRun(Object(PHPUnit_Framework_TestSuite), Array)
#9 /usr/share/php/PHPUnit/TextUI/Command.php(129): PHPUnit_TextUI_Command->run(Array, true)
#10 /usr/bin/phpunit(53): PHPUnit_TextUI_Command::main()
#11 {main}"
Run Code Online (Sandbox Code Playgroud)


Ara*_*yan 10

我刚刚写了一个名为"get_caller"的版本,我希望它有所帮助.我很懒.你可以从一个函数运行get_caller(),你不必像这样指定它:

get_caller(__FUNCTION__);
Run Code Online (Sandbox Code Playgroud)

这是完整的脚本,有一个古怪的测试用例:

<?php

/* This function will return the name string of the function that called $function. To return the
    caller of your function, either call get_caller(), or get_caller(__FUNCTION__).
*/
function get_caller($function = NULL, $use_stack = NULL) {
    if ( is_array($use_stack) ) {
        // If a function stack has been provided, used that.
        $stack = $use_stack;
    } else {
        // Otherwise create a fresh one.
        $stack = debug_backtrace();
        echo "\nPrintout of Function Stack: \n\n";
        print_r($stack);
        echo "\n";
    }

    if ($function == NULL) {
        // We need $function to be a function name to retrieve its caller. If it is omitted, then
        // we need to first find what function called get_caller(), and substitute that as the
        // default $function. Remember that invoking get_caller() recursively will add another
        // instance of it to the function stack, so tell get_caller() to use the current stack.
        $function = get_caller(__FUNCTION__, $stack);
    }

    if ( is_string($function) && $function != "" ) {
        // If we are given a function name as a string, go through the function stack and find
        // it's caller.
        for ($i = 0; $i < count($stack); $i++) {
            $curr_function = $stack[$i];
            // Make sure that a caller exists, a function being called within the main script
            // won't have a caller.
            if ( $curr_function["function"] == $function && ($i + 1) < count($stack) ) {
                return $stack[$i + 1]["function"];
            }
        }
    }

    // At this stage, no caller has been found, bummer.
    return "";
}

// TEST CASE

function woman() {
    $caller = get_caller(); // No need for get_caller(__FUNCTION__) here
    if ($caller != "") {
        echo $caller , "() called " , __FUNCTION__ , "(). No surprises there.\n";
    } else {
        echo "no-one called ", __FUNCTION__, "()\n";
    }
}

function man() {
    // Call the woman.
    woman();
}

// Don't keep him waiting
man();

// Try this to see what happens when there is no caller (function called from main script)
//woman();

?>
Run Code Online (Sandbox Code Playgroud)

man()调用woman(),调用get_caller().get_caller()不知道是谁调用它,因为女人()是谨慎的,并没有告诉它,所以它试图找出答案.然后它返回名为woman()的人.并且浏览器中源代码模式下的打印输出显示了函数堆栈:

Printout of Function Stack: 

Array
(
    [0] => Array
        (
            [file] => /Users/Aram/Development/Web/php/examples/get_caller.php
            [line] => 46
            [function] => get_caller
            [args] => Array
                (
                )

        )

    [1] => Array
        (
            [file] => /Users/Aram/Development/Web/php/examples/get_caller.php
            [line] => 56
            [function] => woman
            [args] => Array
                (
                )

        )

    [2] => Array
        (
            [file] => /Users/Aram/Development/Web/php/examples/get_caller.php
            [line] => 60
            [function] => man
            [args] => Array
                (
                )

        )

)

man() called woman(). No surprises there.
Run Code Online (Sandbox Code Playgroud)

  • 此外,您可以为堆栈中的任何名称调用get_caller(someFunctionName).因此,如果wife()调用man(),man()调用woman(),你可以找到女人()中调用man()并挂断的人. (2认同)

ran*_*ame 6

我需要一些东西来仅列出调用类/方法(在Magento项目上工作)。

尽管debug_backtrace提供了大量有用的信息,但是它为Magento安装喷出的信息量却是巨大的(超过82,000行!)由于我只关心调用函数类,因此我做了以下小解决方案:

$callers = debug_backtrace();
foreach( $callers as $call ) {
    echo "<br>" . $call['class'] . '->' . $call['function'];
}
Run Code Online (Sandbox Code Playgroud)


ken*_*orb 5

获取父函数名称的最简单方法是:

$caller = next(debug_backtrace())['function'];
Run Code Online (Sandbox Code Playgroud)