문제

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.

( "및/또는";-))를 알아 내기 위해 첫 번째 페이지의 매뉴얼 페이지를 참조하십시오.

다른 팁

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

Backthrace는 필요하지 않은 많은 쓰레기를 버립니다. 시간이 매우 길고 읽기가 어렵습니다. 당신이 원하는 것은 "어디에서 무엇을 불렀습니까?"입니다. 다음은 간단한 정적 기능 솔루션입니다. 나는 보통 '디버그'라는 클래스에 넣습니다. 여기에는 모든 디버깅 유틸리티 기능이 포함되어 있습니다.

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>
<?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());
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top