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

时间:2022-02-18 23:45:26

This question already has an answer here:

这个问题已经有了答案:

I am aware of function debug_backtrace, but I am looking for some ready to use implementation of function like GetCallingMethodName()? It would be perfect if it gave method's class too (if it is indeed a method).

我知道函数debug_backtrace,但是我正在寻找一些准备好使用GetCallingMethodName()之类的函数实现的东西。如果它也给出方法的类(如果它确实是一个方法),那么它就是完美的。

10 个解决方案

#1


114  

The debug_backtrace() function is the only way to know this, if you're lazy it's one more reason you should code the GetCallingMethodName() yourself. Fight the laziness! :D

debug_backtrace()函数是了解这一点的惟一方法,如果您很懒,这是您应该自己编写GetCallingMethodName()的另一个原因。与懒惰!:D

#2


377  

The simplest way is:

最简单的方法是:

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

#3


26  

As of php 5.4 you can use

对于php 5.4,您可以使用

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

This will not waste memory as it ignores arguments and returns only the last 2 backtrace stack entries, and will not generate notices as other answers here.

这不会浪费内存,因为它会忽略参数,只返回最后两个回溯堆栈条目,并且不会像这里的其他答案那样生成通知。

#4


23  

You can also use the info provided by a php exception, it's an elegant solution:

您还可以使用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');

And you get this... (voilà!)

你得到这个……(瞧!)

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

)

#5


16  

My favourite way, in one line!

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

You can use it like this:

你可以这样使用:

echo 'The calling function: ' . debug_backtrace()[1]['function'];

Note that this is only compatible with versions of PHP released within the last year. But it's a good idea to keep your PHP up to date anyway for security reasons.

注意,这只与去年发布的PHP版本兼容。但出于安全考虑,最好随时更新PHP。

#6


11  

For me debug_backtrace was hitting my memory limit, and I wanted to use this in production to log and email errors as they happen.

对我来说,debug_backtrace达到了内存限制,我想在产品中使用它来记录和邮件错误。

Instead I found this solution which works brilliantly!

相反,我发现这个解决方案非常有效!

// 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}"

#7


8  

I just wrote a version of this called "get_caller", I hope it helps. Mine is pretty lazy. You can just run get_caller() from a function, you don't have to specify it like this:

我刚写了一个名为“get_caller”的版本,希望它能帮上忙。我很懒。可以从函数中运行get_caller(),不需要这样指定:

get_caller(__FUNCTION__);

Here's the script in full with a quirky test case:

下面是一个带有古怪测试用例的完整脚本:

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

?>

man() calls woman(), who calls get_caller(). get_caller() doesn't know who called it yet, because the woman() was cautious and didn't tell it, so it recurses to find out. Then it returns who called woman(). And the printout in source-code mode in a browser shows the function stack:

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.

#8


3  

I needed something to just list the calling classes/methods (working on a Magento project).

我需要一些东西来列出调用类/方法(处理Magento项目)。

While debug_backtrace provides tons of useful information, the amount of information it spewed out for the Magento installation was overwhelming (over 82,000 lines!) Since I was only concerned with the calling function and class, I worked this little solution up:

虽然debug_backtrace提供了大量有用的信息,但是它为Magento安装提供的信息实在太多了(超过82,000行!)由于我只关心调用函数和类,所以我使用了这个小的解决方案:

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

#9


3  

The simplest way of getting parent function name is:

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

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

#10


0  

Best answer of that question I've seen is:

这个问题的最佳答案是:

list(, $caller) = debug_backtrace(false);

Short and clean

短的和干净的

#1


114  

The debug_backtrace() function is the only way to know this, if you're lazy it's one more reason you should code the GetCallingMethodName() yourself. Fight the laziness! :D

debug_backtrace()函数是了解这一点的惟一方法,如果您很懒,这是您应该自己编写GetCallingMethodName()的另一个原因。与懒惰!:D

#2


377  

The simplest way is:

最简单的方法是:

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

#3


26  

As of php 5.4 you can use

对于php 5.4,您可以使用

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

This will not waste memory as it ignores arguments and returns only the last 2 backtrace stack entries, and will not generate notices as other answers here.

这不会浪费内存,因为它会忽略参数,只返回最后两个回溯堆栈条目,并且不会像这里的其他答案那样生成通知。

#4


23  

You can also use the info provided by a php exception, it's an elegant solution:

您还可以使用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');

And you get this... (voilà!)

你得到这个……(瞧!)

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

)

#5


16  

My favourite way, in one line!

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

You can use it like this:

你可以这样使用:

echo 'The calling function: ' . debug_backtrace()[1]['function'];

Note that this is only compatible with versions of PHP released within the last year. But it's a good idea to keep your PHP up to date anyway for security reasons.

注意,这只与去年发布的PHP版本兼容。但出于安全考虑,最好随时更新PHP。

#6


11  

For me debug_backtrace was hitting my memory limit, and I wanted to use this in production to log and email errors as they happen.

对我来说,debug_backtrace达到了内存限制,我想在产品中使用它来记录和邮件错误。

Instead I found this solution which works brilliantly!

相反,我发现这个解决方案非常有效!

// 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}"

#7


8  

I just wrote a version of this called "get_caller", I hope it helps. Mine is pretty lazy. You can just run get_caller() from a function, you don't have to specify it like this:

我刚写了一个名为“get_caller”的版本,希望它能帮上忙。我很懒。可以从函数中运行get_caller(),不需要这样指定:

get_caller(__FUNCTION__);

Here's the script in full with a quirky test case:

下面是一个带有古怪测试用例的完整脚本:

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

?>

man() calls woman(), who calls get_caller(). get_caller() doesn't know who called it yet, because the woman() was cautious and didn't tell it, so it recurses to find out. Then it returns who called woman(). And the printout in source-code mode in a browser shows the function stack:

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.

#8


3  

I needed something to just list the calling classes/methods (working on a Magento project).

我需要一些东西来列出调用类/方法(处理Magento项目)。

While debug_backtrace provides tons of useful information, the amount of information it spewed out for the Magento installation was overwhelming (over 82,000 lines!) Since I was only concerned with the calling function and class, I worked this little solution up:

虽然debug_backtrace提供了大量有用的信息,但是它为Magento安装提供的信息实在太多了(超过82,000行!)由于我只关心调用函数和类,所以我使用了这个小的解决方案:

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

#9


3  

The simplest way of getting parent function name is:

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

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

#10


0  

Best answer of that question I've seen is:

这个问题的最佳答案是:

list(, $caller) = debug_backtrace(false);

Short and clean

短的和干净的