2017-12-31 161 views
6

register_tick_function()을 사용하여 다음 호출을 연결하고 debug_backtrace()과 함께 스택 추적을 인쇄하려고합니다.register_tick_function()에 의해 호출 된 PHP debug_backtrace()가 전체 스택을 반환하지 않음

다음 코드를 실행하면.

<?php 

function dump() { 
    // Replace this with var_dump(debug_backtrace()); to print the entire trace. 
    foreach (debug_backtrace() as $trace) 
    echo("Function ${trace['function']}() has been called" . PHP_EOL); 
} 

declare(ticks = 1); 
register_tick_function('dump'); 

print(""); 
array_search('green', Array()); 

dump() 기능 만 인쇄합니다.

Function dump() has been called 
Function dump() has been called 
Function dump() has been called 

이유는 print()array_search() 추적 데이터를 확인할 수 없습니다? dump()을 호출하기 전에 스택이 재설정 된 것과 같습니다. 나는 또한 과거에 제대로 작동했는지 확신합니다.

+2

: https://bugs.php.net/bug.php? id = 70188 –

+0

테스트 됨. Win, Ubuntu, docker (우분투)에서 PHP 7.1로 복제 할 수 없습니다. Win, Ubuntu, docker (우분투)에서 PHP 5.6에서 복제 할 수 없습니다. –

+1

http://phpio.net/s/6v6g에서이 기능을 시험해 보았습니다. PHP 버전에서는 작동하지 않는 것으로 보입니다. 그래서 이것을 보아라 : https://stackoverflow.com/questions/7241834/debug-backtrace-from-registered-shutdown-function-in-php. 그 하나는 register_shutdown_function에 관한 것이지만, 동일 할 수도 있습니다. 추적은 호출되는 위치에서만 시작할 수 있습니다.이 경우에는 발생하지 않을 수 있습니다. 그것은 더 같이있다 :;' '덤프();' 'array_search ('녹색', 배열());' '덤프(); '인쇄 ("")이 경우에 따라서' , 그것을 다른 어떤 것에서도 호출되지 않기 때문에 실제로 그 자체를 추적합니다. – Huy

답변

1

백 트레이스에 대한 오해가 있습니다.이 스택은 특정 코드 행에 도달하기 전에 PHP가 실행 한 함수 목록이 아니라 PHP의 인터프리터가 특정 코드 행에 있음을 정당화하는 중첩 함수 목록입니다 .

첫 번째 요소는 항상 현재있는 함수이고 다음 요소는 해당 함수를 호출 한 함수입니다. 함수가 반환되면 더 이상 스택에 없습니다.

class Foo { 
    public static function bar() { 
     return self::say(); 
    } 

    public static function say() { 
     return debug_backtrace(); 
    } 
} 

var_dump(Foo::say()); 
//[0] => say() 

var_dump(Foo::bar()); 
//[0] => say(); 
//[1] => bar(); 

//Note that this behaviour work the same for require(), include() and eval() 

require_once('test.php'); 

//test.php: 
var_dump(debug_backtrace()); 
//[0] => require_once() 

PHP는 스크립트를 해석하기 때문에 함수를 탐색하여 현재 스택에서 추가 및 제거합니다. 백 트레이스의 스택은 PHP가 어떤 함수가 연대순으로 호출되었는지를 기록하는 장소가 아닙니다.

후자의 경우

, 이것은 내가 찾은 해결책은 다음과 같습니다이 몇 년 전에 버그로보고,하지만 재현 아니었다 Get a called functions list in PHP