Programing

PHP 호출 스택 인쇄

lottogame 2020. 4. 11. 09:38
반응형

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

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


참조하십시오 debug_print_backtrace. flush원한다면 나중에 전화 할 수있을 것 같아요 .


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 

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


이 utils 클래스를 살펴보십시오. 도움이 될 수 있습니다.

용법:

<?php
/* first caller */
 Who::callme();

/* list the entire list of calls */
Who::followme();

소스 클래스 : https://github.com/augustowebd/utils/blob/master/Who.php


debug_backtrace()


당신은 debug_backtrace, 또는 아마 보고 싶을 수도 있습니다 debug_print_backtrace.


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

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

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


위의 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());

참고 URL : https://stackoverflow.com/questions/1423157/print-php-call-stack

반응형