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

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

283962 次浏览

debug_backtrace()函数是知道这一点的唯一方法,如果你很懒,这是你应该自己编写GetCallingMethodName()的另一个原因。战胜懒惰!: D

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

get_caller(__FUNCTION__);

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

<?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()调用woman(),后者调用get_caller()。Get_caller()还不知道是谁调用了它,因为woman()很谨慎,没有告诉它,所以它递归查找。然后返回谁调用了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.

你也可以使用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
)


)

最简单的方法是:

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

正如下面的评论所指出的,可以通过将参数传递给:

  • 省略objectargs索引
  • 限制返回的堆栈帧数
echo debug_backtrace(!DEBUG_BACKTRACE_PROVIDE_OBJECT|DEBUG_BACKTRACE_IGNORE_ARGS,2)[1]['function'];

我所见过的这个问题的最佳答案是:

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

简洁明了

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

虽然debug_backtrace提供了大量有用的信息,但它为Magento安装提供的信息量是压倒性的(超过82,000行!)因为我只关心调用函数而且类,所以我想出了这个小解决方案:

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

对我来说,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}"

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

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

我最喜欢的方式,一句话!

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

你可以这样使用它:

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

注意,这只与去年发布的PHP版本兼容。但出于安全考虑,让PHP保持最新是一个好主意。

从php 5.4开始就可以使用

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

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