[php] PHP 호출 스택 인쇄

PHP에서 호출 스택을 인쇄하는 방법을 찾고 있습니다.

함수가 IO 버퍼를 플러시하는 경우 보너스 포인트.



답변

역 추적을 생성하려면 debug_backtrace및 / 또는를 찾고 debug_print_backtrace있습니다.

예를 들어 첫 번째 것은 다음과 같은 배열을 가져옵니다 (매뉴얼 인용) :

array(2) {
[0]=>
array(4) {
    ["file"] => string(10) "/tmp/a.php"
    ["line"] => int(10)
    ["function"] => string(6) "a_test"
    ["args"]=>
    array(1) {
      [0] => &string(6) "friend"
    }
}
[1]=>
array(4) {
    ["file"] => string(10) "/tmp/b.php"
    ["line"] => int(2)
    ["args"] =>
    array(1) {
      [0] => string(10) "/tmp/a.php"
    }
    ["function"] => string(12) "include_once"
  }
}

분명히 I / O 버퍼를 플러시하지는 않지만 flush및 / 또는를 사용하여 직접 수행 할 수 있습니다 ob_flush.

( “and / or”;-) 이유를 찾으려면 첫 번째 매뉴얼 페이지를 참조하십시오)


답변

보다 읽기 쉬운 debug_backtrace():

$e = new \Exception;
var_dump($e->getTraceAsString());

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


답변

추적을 기록하려면

$e = new Exception;
error_log(var_export($e->getTraceAsString(), true));

감사합니다 @Tobiasz


답변

역 추적은 불필요한 많은 쓰레기를 버립니다. 시간이 오래 걸리고 읽기가 어렵습니다. 평소에 원했던 것은 “무엇에서 무엇을 불렀습니까?” 다음은 간단한 정적 함수 솔루션입니다. 나는 보통 디버깅 유틸리티 함수를 모두 포함하는 ‘debug’라는 클래스에 넣었다.

class debugUtils {
    public static function callStack($stacktrace) {
        print str_repeat("=", 50) ."\n";
        $i = 1;
        foreach($stacktrace as $node) {
            print "$i. ".basename($node['file']) .":" .$node['function'] ."(" .$node['line'].")\n";
            $i++;
        }
    }
}

당신은 이것을 다음과 같이 부릅니다.

debugUtils::callStack(debug_backtrace());

그리고 다음과 같은 출력을 생성합니다.

==================================================
 1. DatabaseDriver.php::getSequenceTable(169)
 2. ClassMetadataFactory.php::loadMetadataForClass(284)
 3. ClassMetadataFactory.php::loadMetadata(177)
 4. ClassMetadataFactory.php::getMetadataFor(124)
 5. Import.php::getAllMetadata(188)
 6. Command.php::execute(187)
 7. Application.php::run(194)
 8. Application.php::doRun(118)
 9. doctrine.php::run(99)
 10. doctrine::include(4)
==================================================


답변

아무도 이런 식으로 게시하지 않은 이상한 :

debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

이것은 실제로 가비지없이 역 추적을 인쇄합니다.


답변

PHP 가이 기능을 사용하는 것보다 예외 스택 추적을 형식화하는 방법과 매우 유사한 스택 추적을 원한다면 다음과 같이 작성했습니다.

function debug_backtrace_string() {
    $stack = '';
    $i = 1;
    $trace = debug_backtrace();
    unset($trace[0]); //Remove call to this function from stack trace
    foreach($trace as $node) {
        $stack .= "#$i ".$node['file'] ."(" .$node['line']."): ";
        if(isset($node['class'])) {
            $stack .= $node['class'] . "->";
        }
        $stack .= $node['function'] . "()" . PHP_EOL;
        $i++;
    }
    return $stack;
} 

그러면 다음과 같은 형식의 스택 추적이 반환됩니다.

#1 C:\Inetpub\sitename.com\modules\sponsors\class.php(306): filePathCombine()
#2 C:\Inetpub\sitename.com\modules\sponsors\class.php(294): Process->_deleteImageFile()
#3 C:\Inetpub\sitename.com\VPanel\modules\sponsors\class.php(70): Process->_deleteImage()
#4 C:\Inetpub\sitename.com\modules\sponsors\process.php(24): Process->_delete() 


답변

var_dump(debug_backtrace());

그게 당신이 원하는 것을합니까?