PHP : 함수가 어디에서 호출되었는지 확인


93

PHP의 함수가 어디에서 호출되었는지 알아내는 방법이 있습니까? 예:

function epic()
{
  fail();
}

function fail()
{
  //at this point, how do i know, that epic() has called this function?
}

답변:


128

사용할 수 있습니다 debug_backtrace().

예:

<?php

function epic( $a, $b )
{
    fail( $a . ' ' . $b );
}

function fail( $string )
{
    $backtrace = debug_backtrace();

    print_r( $backtrace );
}

epic( 'Hello', 'World' );

산출:

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
                )

        )

)

5
처음으로 나는 debug_backtrace()훌륭한 기능을 발견 했습니다. 이걸 사용하겠습니다!
David Yell 2012

26

사용 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()...
    }
}

9
그것은 당신이 원하는 것을 확실히합니다. 그러나 조심하십시오 debug_backtrace(). 콜 체인을 결정하는 데 사용하는 습관을 갖지 마십시오. 이러한 기능을 "보호"하려면 OOP 및 보호 방법을 확인하십시오.
ircmaxell 2010-06-02

18

내가 찾은 가장 빠르고 간단한 솔루션

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] => ->
        )

)

Lenovo 노트북에서 속도를 테스트했습니다 : 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;

결과 :

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

나에게 DEBUG_BACKTRACE_IGNORE_ARGS는 너무 많은 정보가 없이는 매우 유용했습니다.
Arie

15

따라서 여전히 방법을 모른다면 여기보다 해결책이 있습니다.

$backtrace = debug_backtrace();
echo 'Mu name is '.$backtrace[1]['function'].', and I have called him! Muahahah!';

1
따라서 if ($ backtrace [1] [ 'function'] == 'epic') {// 몇 가지 작업을 수행 할 수 있습니다. 그렇지 않으면 다른 일을합니다. } ?? 와우
Buttle Butkus 2012-08-14

2
예,하지만하지 마세요! 어쨌든 영구 응용 프로그램 코드가 아닙니다. 매개 변수를 사용하십시오. debug_backtrace ()는 꽤 무거운 작업처럼 보입니다.
Kluny 2014


3

아래 코드를 시도하십시오.

foreach(debug_backtrace() as $t) {              
   echo $t['file'] . ' line ' . $t['line'] . ' calls ' . $t['function'] . "()<br/>";
}

특정 함수가 호출 된 모든 파일을 추적하는 좋은 직접적인 솔루션입니다.
예외 사항

3

스택 맨 위에서 호출의 정확한 출처를 추적하려면 다음 코드를 사용할 수 있습니다.

$call_origin = end(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));

이것은 연결된 함수를 무시하고 가장 관련성이 높은 호출 정보 만 가져옵니다 (relevant는 수행하려는 작업에 따라 느슨하게 사용됨).


감사합니다. 그 :) 나를 위해 많은 시간을 저장
모하메드 헤샴에게

-1
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");

누군가에게 도움이되기를 바랍니다. 실제 기능이 httpdocs 외부에 있으면 서버가이를 허용하지 않도록 설정되므로 찾을 수 없습니다. 하나의 폴더 깊이 만 테스트했지만 재귀 적 방법론은 이론적으로 작동해야합니다.

이것은 버전 0.1과 같지만 계속 개발할 계획이 없으므로 누군가 업데이트하면 자유롭게 다시 게시 할 수 있습니다.


너무 많은 작업 : 이것을 .bashrc에 추가 function ff() { grep "function $1" $(find ./ -name "*.php") } 한 다음 ff fail또는 ff epic. 참조 : github.com/MaerF0x0/VimSetup/blob/master/bashrc#L122
Mike Graf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.