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

问题描述:

我知道功能debug_backtrace,但我正在寻找一些准备使用像GetCallingMethodName()功能的实现?如果它也给方法的类也是完美的(如果它确实是一种方法)。如何在PHP中获取调用函数/方法的名称?

debug_backtrace()功能是知道这一点的唯一方法,如果你懒惰,那么你应该自己编码GetCallingMethodName()的另一个原因。 战斗懒惰! :D

+13

“战斗的懒惰!d” 但是懒惰是一件好事: http://www.codinghorror.com/blog/archives/000237.html :} 所以,如果有人写这样的功能,我真的很感激...:} – JohnM2 2010-01-21 16:37:25

+19

谁需要谷歌,而像这样一个伟大的'编程答案搜索引擎'像你这样的计算器用户:} http://stackoverflow.com/questions/190421/caller-function-in -php-5/190426#190426 现在认真,谢谢! – JohnM2 2010-01-21 18:44:15

+3

为了获得更好的性能,请传递这些参数'debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,2)'。 – anwerj 2016-11-15 10:59:53

我刚刚写了一个名为“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(); 

?> 

人()调用调用get_caller()的女士()。 get_caller()不知道是谁调用它,因为女人()很谨慎,并没有告诉它,所以它会反复查找。然后它返回谁称为女人()。并在浏览器的源代码模式下的打印输出显示功能栈:

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. 
+2

此外,您可以调用get_caller(someFunctionName)来获取当前堆栈中的任何名称。所以如果妻子()称为男人(),而男人()称为女人(),那么你可以在女人()中找出谁叫人()并挂断电话。 – 2011-01-22 13:25:14

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

) 
+1

伟大的解决方案!为我工作。 – 2012-05-10 22:32:43

+2

有趣的方法,我有点喜欢它,但它为什么比使用debug_backtrace更好? – ken 2012-06-23 19:13:00

+2

请注意,我做了一个快速基准测试,看起来像这个解决方案比debug_backtrace()慢2倍。 但是,我们正在讨论微优化,直到您不经常在代码中使用此方法 – Strae 2012-08-22 09:34:43

最简单的方法是:

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

为什么这不被标记为正确答案? – MCMXCII 2016-01-12 15:37:57

+0

是的,这是正确的答案。每当我需要它时,我都会不断回来并提及它。 – 2016-04-07 13:29:17

+1

刚发现这个。非常有用,但值得注意的是这里可​​能涉及大量开销。我运行了'print_r(debug_backtrace())',它基本上使我的浏览器崩溃,并返回了它的信息。 – Utkanos 2016-07-22 11:41:06

最好这个问题,我已经看到的答案是:

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

短和清洁

+1

'debug_backtrace()[1] ['function']'不具有吸引力吗? – AgileTillIDie 2013-07-11 19:47:28

+4

@AgileTillIDie这只会在php> = 5.4中工作。由于对list()的更改不再接受空参数,因此 – quickshiftin 2013-08-18 15:38:53

+1

将不会像'php> = 7'那样工作。 http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.variable-handling.list。清空 – fyrye 2016-06-09 14:42:04

我需要的东西,只是列出调用类/方法(在Magento的项目工作)。

虽然debug_backtrace提供了大量实用的资讯,信息就喷涌出来Magento的安装量巨大(超过82000行!)因为我只关心调用函数类,我工作这么小的解决方案达:

$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始终保持最新状态。

+1

此方法已经提供了无数次,并且问题在于它只能在PHP 5.4或更高版本上运行。 – 2014-10-12 00:43:45

+1

哈哈谢谢@ialarmedalien:D至于兼容性,我可能太过侵略性的更新?我觉得人们应该保持他们的PHP(合理)最新。它是免费的,并且使用过时的软件具有安全风险。当你使用2或3年前的PHP版本时,你不仅会失去这样的好功能,还会让你的服务器面临风险。 – gavanon 2014-10-12 18:53:12

+3

@gavanon该评论表明对PHP和最流行的工具的维护方式缺乏了解。在PHP 5.4发布后,PHP 5.3继续接收* years *的安全问题更新。只是作为一个旧版本的PHP并不意味着你必须在*不安全的PHP上。 – meagar 2016-02-03 22:08:15

由于PHP 5.4,你可以用

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

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

+0

你测试过了吗? – 2015-03-14 22:31:23

+2

@Krzysztof Trzos试试'echo $ caller;'并且应该可以工作。 ;-) – Minister 2016-02-10 21:47:01

+0

这应该是被接受的答案。 – 2016-12-27 10:22:56