PHP, 이 함수가 어디에서 실행되는 건지, 파일이 어디에서 인클루드되는 건지 찾아야 할 때

라라벨에서 페이지 한 번을 로드하는데 layouts.title 뷰가 거의 100번 로드되고 있었습니다. 근데 이게 어디에서 인클루드되고 있는지 찾을 수가 없었습니다. 라라벨 디버그바는 어떤 뷰가 몇 번 컴파일됐는지는 알려 주는데 어디에서 인클루드를 했는지까지는 알려 주지 않습니다.

debug_backtrace 함수

그래서 별도 코드가 필요했는데요. 인클루드되는 파일에 아래처럼 넣으면 간단하게 찾을 수 있습니다(debug_backtrace PHP 문서). 특정 함수가 어디에서 실행되는지 찾는 거라면 그 함수에 넣으면 됩니다.

print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10))

// 로그에 남기려면 아래처럼 합니다.
// print_r의 두 번째 파라미터로 true를 넘긴 것입니다.
// Log::debug는 가상의 코드입니다. 자신의 프로젝트에 맞게 사용하세요.
Log::debug(print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10), true));

이렇게 하면 아래처럼 깔끔하게 백트레이스(이 코드가 어떤 경로를 거쳐 실행됐는지 보여 주는 것)를 찍어 줍니다.

Array
(
[0] => Array
(
[file] => /project/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php
[line] => 107
[function] => require
)
...
[9] => Array
(
[file] => /project/storage/framework/views/ce86911781e5428b862d0801e580faa5538e6e02.php
[line] => 25
[function] => getTitleHtml
[class] => App\Content
[type] => ->
)
)

9번 배열에 들어 있는 값을 보면 storage/framework/views/ce86911781e5428b862d0801e580faa5538e6e02.php 파일의 25번째 라인에서 getTitleHtml()이 호출되면서 이 뷰가 호출됐다는 것을 알 수 있습니다.

위 경우는 라라벨 뷰인데요. 그래서 ce86911781e5428b862d0801e580faa5538e6e02.php 처럼 컴파일된 결과물이 찍혔습니다. 블레이드가 아니라면 프로젝트의 PHP 파일 경로가 나올 겁니다.

라라벨 블레이드의 컴파일 결과물은 보통의 PHP 코드입니다. 이 파일의 맨 맽에는 원본 블레이드 파일 경로가 주석으로 적혀 있습니다. 아래처럼 말입니다.

<?php /**PATH /project/resources/views/unexpected-list.blade.php ENDPATH**/ ?>

매개변수 설명

  • DEBUG_BACKTRACE_IGNORE_ARGS: 이 옵션을 지정하면 반환되는 배열에서 함수의 인수들은 제외됩니다. 다 나오게 하려면 0을 넣으면 됩니다. 그런데 그렇게 하니 저는 메모리 초과가 뜨는군요. 웬만하면 이 옵션을 사용하는 게 좋을 것 같습니다.
  • 10: 보여 줄 최대 단계수를 설정하는 값입니다. 10으로 하면 10단계까지만 거슬러 올라갑니다. 깊이가 깊은 경우 필요한 정보만 보는 데 유용하겠죠. 다 나오게 하려면 0을 넣으면 됩니다. 기본값이 0이니 그냥 안 쓰면 됩니다.

로그용 코드라면

참고로 영구적으로 사용할 디버그 로깅 코드라면 print_r을 거쳐 여러 줄로 만들기보다는 아래처럼 한 줄로 남기는 편이 나을 겁니다. 이렇게 남기면 모든 데이터를 한 줄로 남기게 됩니다. 사람이 읽기는 힘들지만 grep 같은 도구로 로그를 검색할 때는 좋습니다. (아래 코드는 라라벨에서 로그를 남기는 코드이므로 라라벨이 아닌 경우엔 다르게 하셔야 합니다.)

Log::debug('title.blade.php is rendered.', ['trace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10)]);

결론

기본적으로는 수동으로 백트레이스를 찍는 방법을 사용한 것입니다. 그래서 핵심은 debug_backtrace 함수를 기억하자는 것이죠.

(참고로 debug_print_backtrace 함수도 있습니다. 이건 바로 출력을 합니다.)

카테고리 글 목록 👉

대표글

댓글 남기기