PHP 호출 스택 인쇄


답변:


123

역 추적을 생성하려면 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";-) 이유를 찾으려면 첫 번째 매뉴얼 페이지를 참조하십시오)


7
이것은 정기적으로 내 PHP에 메모리가 부족하게합니다. Tobiasz의 솔루션을 추천합니다.
peedee

읽기 / 이해하기 어려운 경우 Tobiasz의 솔루션
ViliusL을 추천합니다.

1
@peedee는 옵션 DEBUG_BACKTRACE_IGNORE_ARGS매개 변수 중 하나를 제공하는 것입니다 . 기능적으로 동일합니다(new \Exception())->getTraceAsString()

565

보다 읽기 쉬운 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}"

50
젠장, 이것이 훨씬 낫습니다. 왜 이것을 debug_print_backtrace ()의 기본 출력으로 만들 수 없었습니까? 반향되지 않은 변수에 변수를 원하는 사람들을 위해 부울 매개 변수 "returnTrace"를 추가했을 수 있으며 완벽했을 것입니다!
jurchiks

1
작동 것이라고 결코 생각하지 않았다 나는 내가 그 작업을 수행하는 방법을 알아 내려고하고 몇 개월 몰라요
WojonsTech

이 솔루션은 또한 debug_backtrace ()의 출력을 배열로 캡처 한 다음 print_r ()을 사용하여 인쇄하는 것보다 적은 메모리를 사용하는 것으로 보입니다.
피터

5
나는 debug_backtracestacktrace에서 첫 번째 수준 만 반환 하도록 제한하는 방법을 찾고있었습니다. 이 솔루션은 저에게 효과적입니다. 감사합니다!
ankr

3
@Andrew print_r는 모든 메시지를 보관합니다.
mopo922

41

추적을 기록하려면

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

감사합니다 @Tobiasz


35

역 추적은 불필요한 많은 쓰레기를 버립니다. 시간이 오래 걸리고 읽기가 어렵습니다. 평소에 원했던 것은 "무엇에서 무엇을 불렀습니까?" 다음은 간단한 정적 함수 솔루션입니다. 나는 보통 디버깅 유틸리티 함수를 모두 포함하는 '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)
==================================================


33

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

debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

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


2
실제로, 주요 투표 솔루션과 동일하며 더 짧습니다. 감사합니다
brunetton

9

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() 

2
또는 그냥$e = new Exception; echo $e->getTraceAsString();
브래드 켄트

새 예외에 의한 추적 항목이 표시되지 않도록 브래드, 그 해결책은 스택 추적에서 마지막 항목을 제거하지 않습니다
TroySteven

8
var_dump(debug_backtrace());

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



4

phptrace 는 확장 기능을 설치하지 않고 언제든지 PHP 스택을 인쇄 할 수있는 훌륭한 도구입니다.

phptrace에는 두 가지 주요 기능이 있습니다 : 첫째, 아무것도 설치하지 않아도되는 PHP의 인쇄 호출 스택, 둘째, 제공하는 확장 기능을 설치해야하는 추적 PHP 실행 흐름.

다음과 같이 :

$ ./phptrace -p 3130 -s             # phptrace -p <PID> -s
phptrace 0.2.0 release candidate, published by infra webcore team
process id = 3130
script_filename = /home/xxx/opt/nginx/webapp/block.php
[0x7f27b9a99dc8]  sleep /home/xxx/opt/nginx/webapp/block.php:6
[0x7f27b9a99d08]  say /home/xxx/opt/nginx/webapp/block.php:3
[0x7f27b9a99c50]  run /home/xxx/opt/nginx/webapp/block.php:10 

Windows 버전이 있습니까?
johnny

나는 메모리 주소가 여기에 있습니다 .. 이것은 도움이 될 수 있습니다
Tyler Miles

3

debug_backtrace호출 된 함수 및 메소드와 호출 된 지점으로 이어진 파일에 대한 역 추적을 얻는 데 사용하십시오 debug_backtrace.





1

Walltearer의 솔루션은 특히 'pre'태그로 묶인 경우 우수합니다.

<pre>
<?php debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); ?>
</pre>

-깔끔하게 번호가 매겨진 별도의 회선에 통화를 설정합니다.


0

위의 Don Briggs의 답변 을 공개 인쇄 대신 내부 오류 로깅을 사용 하도록 조정 했습니다. 이는 라이브 서버에서 작업 할 때 큰 문제가 될 수 있습니다. 또한 기본 이름 대신 전체 파일 경로를 포함하는 옵션 (다른 경로에 동일한 이름의 파일이있을 수 있기 때문에)과 완전한 노드 스택 출력을 포함하는 옵션과 같은 몇 가지 수정 사항이 추가되었습니다.

class debugUtils {
    public static function callStack($stacktrace) {
        error_log(str_repeat("=", 100));
        $i = 1;
        foreach($stacktrace as $node) {
            // uncomment next line to debug entire node stack
            // error_log(print_r($node, true));
            error_log( $i . '.' . ' file: ' .$node['file'] . ' | ' . 'function: ' . $node['function'] . '(' . ' line: ' . $node['line'] . ')' );
            $i++;
        }
        error_log(str_repeat("=", 100));
    } 
}

// call debug stack
debugUtils::callStack(debug_backtrace());
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.