/ php

Xdebug? Отладка по-взрослому. И почему ты должен его использовать

XDeubug - это расширение, которое предоставляет продвинутые инструменты по отладке PHP-кода. В этой статье я покажу, как использовать Xdebug, и в чём его преимущество.

XDEЧТО?

Xdebug - это расширение для PHP, которое предоставляет широкие возможности по отладке PHP-приложения. Это расширение позволяет указывать точки остановки (breakpoints), грубо говоря, которые представляют из себя "паузу выполнения" скрипта. Эти breakpoin-ы останавливают выполнение скрипта (в том участке, где было указано), и выводят все текущие доступные данные на момент остановки (переменные и их значения, классы, куки, сессии, и т.д.).

Xdebug полностью исключает необходимость в использовании monkey-дебага, типа:

var_dump($soveVar); //string...
//или
print_r($soveVar); //array...
die();

Почему это удобнее?
Во-первых, breakpoint-ы, ставить проще и быстрее.
Во-вторых, такой структурированной и полной информации не добиться ни от какой из существующих debug-функций.
А в-третьих, используя это расширение, можно менять значения любых переменных налету, изучая влияние новых значений на приложение в целом.

Поддержка в IDE и текстовом редакторе

Большинство современных IDE без проблем поддерживают xdebug. Настройка индивидуальна, в зависимости от выбранной IDE (возможно, потребуется дополнительная установка плагинов). Например, в SublimeText, Netbeans, или даже в Notepad++ предоставляются возможности по использованию дебаггера.

Моя любимая IDE уже имеет встроенную поддержку xdebug-а. Потому, настройка здесь ещё проще, чем хотелось бы.
По правде говоря, лучше IDE, чем PhpStorm, я пока не встречал, и именно про такие программы говорят: "она стоит каждого своего цента". Потому, я советую в разработке использовать именно её. Потому, все скриншоты будут исключительно из PhpStorm-а.

Установка XDEBUG

Установка в разных операционных системах отличается. Я же использую windows, openserver. Потому, продемонстрирую пошаговую инструкцию установки xdebug на openserver.

Заходим в php.ini
openserverphp-ini-2

Находим меню [Xdebug]
xdebug-php-1
В котором, ищем, и устанавливаем параметры (в основном они закомментированы, потому, нужно раскомментировать их, удалив в начале ;):

zend_extension="%sprogdir%/modules/php/%phpdriver%/ext/php_xdebug.dll"
xdebug.idekey = "PHPSTORM"
xdebug.profiler_enable_trigger = 1
xdebug.profiler_output_dir="%sprogdir%/userdata/temp/xdebug/"
xdebug.profiler_output_name = "cachegrind.out.%H%R"
xdebug.remote_enable = 1
xdebug.remote_handler = "dbgp"
xdebug.remote_port = 9000
xdebug.trace_output_dir = "%sprogdir%/userdata/temp/xdebug/"

Сохранив изменения, перезагрузив сервер, и вызвав phpinfo() можно убедиться, что xdebug появился, и стал доступным с указанными ранее параметрами.
xdebug-phpinfo

Теперь, из серверных настроек всё котово. Осталось сделать так, чтобы можно было вызвать дебаггер из браузера. Ранее всё было сложнее, однако, сейчас всё сводится к установке одного расширения google chrome Xdebug helper.

Настройка PHPSTORM

Для настройки IDE нужно перейти в меню File | Settings | Languages & Frameworks | PHP | Debug, где указать ранее указанный порт, равный 9000, и запустить "прослушку"
phpstorm-index-2

И, аналогично, в File | Settings | Languages & Frameworks | PHP | Debug | DBGp Proxy нужно указать IDE KEY, и порт:
phpstorm-odekey

И, готово. Теперь скрипт полностью готов к дебагу. Для проверки, я создал новый домен xdebug.loc. Перейдя по адресу проекта, в панеле расширений, можно заметить новую иконку, открыв которую, и активировав Debug, страница начнёт прослушку:
client

Первый breakpoint

Теперь осталось написать код, и поставить в нём точку остановки. Сделать это просто: достаточно, напротив строки, на которой предполагается остановка, нажать на пустом месте, расположенном скраю.
xdebug-breakpoint-1

И, если всё было настроено правильно, то, открыв текущий проект в браузере, увидим постоянно загружающуюся страницу. А в IDE, одновременно с этим, откроется окно, со всеми доступными параметрами отладки. Вот так и выглядит xdebug панель отладки в PhpStorm:
xdebug-phpstorm-index

Детальный разбор debug-панели

Рассмотрим отладку на примере исходного кода:

function factorial($n) {
    if ($n === 0) {
        return 1;
    }
    return $n * factorial($n - 1);
}

for($i = 0; $i < 10; $i++) {
    $result = factorial($i);
}

Поставив, один breakpoint на строке начала цикла for, изучим возможности отладки.
function-breakpoint

Панель имеет несколько функциональных кнопок управления процессом отладки
pannel-debug

Где F9 - Resume Program, при клике на которую продолжается выполнение скрипта до следующей точки остановки, или до конца скрипта, если дальше breakpoint-ы не заданы.
Ctrl + F2 - останавливает отладку, и обрывает выполнение скрипта, на текущем моменте. Аналогично, выполнению функции die.
F8 - переходит на следующую строку текущего PHP-файла. Не заходя внутрь вызываемых функций и методов.
F7 - переходит на следующую строку PHP-файла. В отличии от F8, проходит по полному стёку вызовов, и переходит в сами функции и методы, которые были вызваны. И, даёт больше информации, в виде отображение локальных данных функций
Блок 1 - показывает полный стёк вызовов, который был пройдён до текущего момента остановки. Здесь можно увидеть вызов всех методов/функций, количество рекурсивных вызовов, и их подробности, с возможностью перехода в то место, откуда это было произведено.
Блок 2 - показывает все доступные переменные на момент текущего breakpoint-a. При переходе на следующий breakpoint, этот список будет изменяться и дополняться, постепенно с выполнением кода. Кликнув правой кнопкой мыши, можно задать любое значение переменной (Set Value), которое будет влиять на остальной код, использующий эту переменную.

Если поставить breakpoint в цикле, то остановка будет срабатывать на каждой его итерации, а не один раз за весь цикл

Если выполнить ранее написанный код, то можно попрактиковаться, используя разные режимы навигации:
F9 - обычный режим перехода
green_bar
В котором, на каждой итерации цикла будут отображаться данные, соответствующие выполнению текущего шага

F8 - построчный вывод кода, без углубления в вызов функций,
2steps-bar

F7 - построчный вывод кода, с проходом по стёку функций,
recurs-block
Теперь, можно отследить весь путь выполнения кода (аналогично интерпретатору), и отследить, как локальные переменные функции, так и глобальные для всей системы.

Отладка чужих проектов

Перед тем, как закончить этот туториал, я хотел бы описать одну очень распространённую проблему при выполнении проектов.
Есть много проектов, которые написаны в виде одного большого полотна кода. Понять логику которого очень сложно. Потому, единственным правильным решением будет вызов xdebug-а с первой строки, и осуществление навигации с помощью рассмотренных выше функций (F8, или F7), построчно изучая логику работы приложения.

Поверьте, но продвинутое знание xdebug-а очень сильно упрощает жизнь программиста

Резюме

Сегодня вы изучили, что такое xdebug, как установить xdebug на open server, и как работать с xdebug в PhpStorm.

Я надеюсь, что этот туториал убедил вас в том, что xdebug лучше, и гибче обычных echo, var_dump, или print_r. При том, что понять, как с ним работать можно быстро, а пользу, которую принесёт его понимание, можно извлечь колоссальную.