php:确定从哪里调用函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/2960805/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
php: determine where function was called from
提问by pol_b
is there a way to find out, where a function in PHP was called from? example:
有没有办法找出PHP中的函数是从哪里调用的?例子:
function epic()
{
  fail();
}
function fail()
{
  //at this point, how do i know, that epic() has called this function?
}
回答by romac
You can use debug_backtrace().
您可以使用debug_backtrace().
Example:
例子:
<?php
function epic( $a, $b )
{
    fail( $a . ' ' . $b );
}
function fail( $string )
{
    $backtrace = debug_backtrace();
    print_r( $backtrace );
}
epic( 'Hello', 'World' );
Output:
输出:
Array
(
    [0] => Array
        (
            [file] => /Users/romac/Desktop/test.php
            [line] => 5
            [function] => fail
            [args] => Array
                (
                    [0] => Hello World
                )
        )
    [1] => Array
        (
            [file] => /Users/romac/Desktop/test.php
            [line] => 15
            [function] => epic
            [args] => Array
                (
                    [0] => Hello
                    [1] => World
                )
        )
)
回答by BoltClock
Use debug_backtrace():
function fail()
{
    $backtrace = debug_backtrace();
    // Here, $backtrace[0] points to fail(), so we'll look in $backtrace[1] instead
    if (isset($backtrace[1]['function']) && $backtrace[1]['function'] == 'epic')
    {
        // Called by epic()...
    }
}
回答by Mariusz Charczuk
Fastest and simplest solution as I found
我发现的最快和最简单的解决方案
public function func() { //function whose call file you want to find
    $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
}
$trace: Array
(
    [0] => Array
        (
            [file] => C:\wamp\www\index.php
            [line] => 56
            [function] => func
            [class] => (func Class namespace)
            [type] => ->
        )
)
I test the speed on Lenovo laptop: Intel Pentiom CPU N3530 2.16GHz, RAM 8GB
我在联想笔记本电脑上测试速度:Intel Pentiom CPU N3530 2.16GHz,RAM 8GB
global $times;
$start = microtime(true);
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
$times[] = microtime(true) - $start;
Results:
结果:
count($times):  97
min:    2.6941299438477E-5
max:   10.68115234375E-5
avg:    3.3095939872191E-5
median: 3.0517578125E-5
sum:  321.03061676025E-5
the same results with notation without E-5
count($times):  97
min:    0.000026941299438477
max:    0.0001068115234375
avg:    0.000033095939872191
median: 0.000030517578125
sum:    0.0032103061676025
回答by marverix
So if you still REALLY don't know how, than here is solution:
因此,如果您仍然真的不知道如何,那么这里是解决方案:
$backtrace = debug_backtrace();
echo 'Mu name is '.$backtrace[1]['function'].', and I have called him! Muahahah!';
回答by Yehonatan
Use the debug_backtrace function: http://php.net/manual/en/function.debug-backtrace.php
使用 debug_backtrace 函数:http://php.net/manual/en/function.debug-backtrace.php
回答by Makwana Ketan
Try below code.
试试下面的代码。
foreach(debug_backtrace() as $t) {              
   echo $t['file'] . ' line ' . $t['line'] . ' calls ' . $t['function'] . "()<br/>";
}
回答by Phillip Weber
If you want to trace the exact origin of the call at the top of the stack you can use the following code:
如果要在堆栈顶部跟踪调用的确切来源,可以使用以下代码:
$call_origin = end(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
This will ignore chained functions and get only the most relevant call info (relevant is used loosely as it depends what your are trying to accomplish).
这将忽略链式函数并仅获取最相关的调用信息(相关使用松散,因为它取决于您要完成的任务)。
回答by Alien
function findFunction($function, $inputDirectory=""){
    //version 0.1
    $docRoot = getenv("DOCUMENT_ROOT");
    $folderArray = null;
    $dirArray = null;
    // open directory
    $directory = opendir($docRoot.$inputDirectory);
    // get each entry
    while($entryName = readdir($directory)) {
        if(is_dir($entryName) && $entryName != "." && $entryName != ".."){
            $folderArray[] = str_replace($inputDirectory, "", $entryName);
        }
        $ext = explode(".", $entryName);
        if(!empty($ext[1])){
            $dirArray[] = $docRoot.$inputDirectory."/".$entryName;
        }
    }
    // close directory
    closedir($directory);
    $found = false;
    if(is_array($dirArray)){
        foreach($dirArray as $current){
            $myFile = file_get_contents($current);
            $myFile = str_replace("<?php", "", $myFile);
            $myFile = str_replace("?>", "", $myFile);
            if(preg_match("/function ".$function."/", $myFile)){
                $found = true;
                $foundLocation = $current;
                break;
            }
        }
    }
    if($found){
        echo $foundLocation;
        exit;
    } else if(is_array($folderArray)){
        foreach($folderArray as $folder){
            if(!isset($return)){
                $return = findFunction($function, $inputDirectory."/".$folder);
            } else if($return == false){
                $return = findFunction($function, $inputDirectory."/".$folder);
            }
        }
    } else {
        return false;
    }
}
findFunction("testFunction", "rootDirectory");
Hope it helps somebody. If the actual function is outside httpdocs then it can not be found because the server will be setup to not allow it. Only tested it one folder deep too but the recursive methodology should work in theory.
希望它可以帮助某人。如果实际功能在 httpdocs 之外,则无法找到它,因为服务器将设置为不允许它。也只测试了一个文件夹深,但递归方法理论上应该有效。
This is like version 0.1 but I don't intend on continuing development on it so if someone updates it feel free to repost it.
这类似于 0.1 版,但我不打算继续开发它,因此如果有人更新它,请随时重新发布。

