Отладка php функций с помощью phpdbg, как альтернатива Xdebug через IDE

Иногда приходится работать с сервером через «кучу» файерволов, c локальным IP c репозиторием и т.д., и по этой причине довольно тяжело настроить XDebug для работы через IDE NetBeans (и прочих IDE). Приходиться проще поднимать локально виртуальную машину. И если XDebug нужен лишь только для того, чтобы по быстрому ознакомиться с большим новым проектом (с кучей легаси кода) с последующей отладкой через error_log, то отлаживать отдельные скрипты довольно не всегда удобно в нем.
Неверно срабатывают точка прерывания, лишний стек вызова подключаемых скриптов и т.д. Как вариант, для знакомства с новым проектом, можно еще настроить xhprof и по быстрому просматривать стек вызова функций на графиках при вызове того или иного скрипта. В этом случае хорошо отлавливать ошибки ненужных вызовов кучи функций в циклах, в которых нет внутри static инициализации переменной. В частности, вызовы одной и той же настройки из базы данных внутри цикла (foreach, for, while, do-while). Отличие phpdbg от выше описанных инструментов в том, что он позволяет отладить конкретно какую то функцию в логике на редкостный баг. Phpdbg это грубо говоря командный (консольный) интерфейс отладки по аналогии как в NetBeans (xdebug). Если в IDE мы кликами мышки указывает точки прерывания (breakpoint-ов), то в Phpdbg это нужно делать в виде команд.

Приведу для примера простой код.





Для выше приведенного PHP кода, для того, чтобы начать отлаживать функцию EugeneKurilov (), необходимо выполнить команду:

prompt> break EugeneKurilov
[Breakpoint #0 added at EugeneKurilov]



А затем,

prompt> run
[Breakpoint #0 in EugeneKurilov() at /root/dbg.php:3, hits: 1]
>00003: function EugeneKurilov() {
 00004:   $i = 10;
 00005:   for($j=0;$j<$i;$j++) {


Нажимая команду s (step), мы проходим по телу функции, для того, чтобы просмотреть, как меняется переменная $j, необходимо выполнить команду watch $j:

[Breakpoint #0 in EugeneKurilov() at /root/dbg.php:3, hits: 1]
>00003: function EugeneKurilov() {
 00004:   $i = 10;
 00005:   for($j=0;$j<$i;$j++) {
prompt> watch $j
[Set watchpoint on $j]



И далее, нажимать s (step) для прохода.

[Breaking on watchpoint $j]
Old value:
New value: 0
>00005:   for($j=0;$j<$i;$j++) {
 00006:      //echo $j;
 00007:   }
prompt>

Old value: 0
New value: 1
>00005:   for($j=0;$j<$i;$j++) {
 00006:      //echo $j;
 00007:   }

Old value: 9
New value: 10
>00005:   for($j=0;$j<$i;$j++) {
 00006:      //echo $j;
 00007:   }
prompt> s
[L5       0x7f9d0c088100 IS_SMALLER              $j                   $i                   ~3                   /root/dbg.php]
[L5       0x7f9d0c088120 EXT_STMT                                                                               /root/dbg.php]
[L5       0x7f9d0c088140 JMPNZ                   ~3                   J6                                        /root/dbg.php]
[L9       0x7f9d0c088160 EXT_STMT                                                                               /root/dbg.php]
>00009: }

prompt> s
[L11      0x7f9d0c0735e0 RETURN                  1                                                              /root/dbg.php]
[Script ended normally]



То есть довольно просто таким образом в живую просматривать как меняется значение переменной и не нужно добавлять код вроде error_log (при просмотре в логе) или echo в броузере.

Phpdbg довольно прост (для изучения функционала необходимо ввести help) и по этой причине нет смысла описывать детально все моменты. Начиная с версии PHP 5.6 он включен по умолчанию. Моей целью данной публикации было показать альтернативный вариант отладки кода. Как показывает моя практике, проход различными debug-инструментами по новому проекту позволяет быстро понять его архитектуру для случая когда нет документации, а проект разрабатывался одновременно большим количеством сотрудников.

© Habrahabr.ru