Отладка 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-инструментами по новому проекту позволяет быстро понять его архитектуру для случая когда нет документации, а проект разрабатывался одновременно большим количеством сотрудников.