Xdebug — расширение PHP для пошаговой отладки и профилирования кода. Оно перехватывает выполнение скрипта, показывает стек вызовов при ошибке и умеет замерять время каждой функции. На проде Xdebug включать нельзя: он замедляет выполнение в разы и открывает лишний вектор атаки, поэтому ставьте его только на staging или в контейнер разработчика.
Зачем нужен Xdebug, если есть error_log
Обычный error_log показывает, что упало, но не показывает,
почему значение переменной оказалось не тем, каким ожидалось. Xdebug
позволяет поставить точку останова в конкретной строке, посмотреть все
переменные в текущей области видимости и пройти код шаг за шагом прямо в
IDE. Для разбора уже случившихся фаталов без остановки процесса пригодится
статья про разбор логов ошибок
PHP.
Отдельный режим — профилирование. Он не останавливает код, а записывает время выполнения каждой функции в файл формата cachegrind, который потом открывают в KCachegrind или Webgrind, чтобы найти самое медленное место в запросе.
Установка на сервере с Ubuntu и Debian
Xdebug ставится как обычное PECL-расширение поверх уже установленного PHP. Версия расширения должна соответствовать версии PHP-FPM:
sudo apt install php8.3-dev php-pear
sudo pecl install xdebug
echo "zend_extension=xdebug.so" | sudo tee /etc/php/8.3/mods-available/xdebug.ini
sudo phpenmod xdebug
sudo systemctl restart php8.3-fpm
Если на сервере несколько версий PHP одновременно, ставить Xdebug нужно для каждой отдельно — подробности в статье про несколько версий PHP на одном сервере.
Настройка режима step debug
С версии Xdebug 3 конфигурация стала явной: режим работы задаётся одной директивой вместо десятка флагов.
| Параметр | Значение | Назначение |
|---|---|---|
| xdebug.mode | debug | включает пошаговую отладку |
| xdebug.client_host | ip IDE | куда слать сигнал отладки |
| xdebug.client_port | 9003 | порт, который слушает IDE |
| xdebug.start_with_request | trigger | отладка по флагу в запросе |
Значение trigger у последнего параметра важно: без него
Xdebug пытается подключиться к IDE на каждом запросе и заметно тормозит
даже staging.
Типичные проблемы подключения
Отладчик не подключается к IDE почти всегда по одной из этих причин:
- Файрвол на сервере блокирует исходящий трафик на порт 9003 — добавьте разрешающее правило для staging-окружения.
- IDE слушает не тот порт: в PhpStorm по умолчанию 9003, но если стоит старая инструкция — может быть указан 9000, конфликтующий с FastCGI.
- Путь на сервере и путь в IDE не совпадают через path mapping — тогда точки останова просто не срабатывают.
- В
php.iniодновременно загружены Xdebug и OPcache с JIT — их совмещение снижает выгоду от обоих и путает профилирование.
Профилирование медленного запроса
Чтобы найти узкое место в конкретном обработчике, включите режим profile точечно, через параметр в URL, не трогая общий конфиг:
xdebug.mode=profile
xdebug.start_with_request=trigger
xdebug.output_dir=/var/log/xdebug
# запрос вида:
# https://staging.example.com/checkout?XDEBUG_PROFILE=1
Файл cachegrind.out.* покажет дерево вызовов с временем
каждой функции. Часто оказывается, что тормозит не PHP, а лишний запрос к
базе внутри цикла — это видно сразу по числу повторов одной и той же
функции.
Чек-лист безопасного использования
Xdebug — инструмент разработки, а не продовой инфраструктуры. Держитесь такого порядка:
- Ставьте Xdebug только на staging или локально, на проде — режим
xdebug.mode=offили расширение вообще не подключено. - Используйте
start_with_request=trigger, чтобы отладка не включалась на каждый случайный запрос. - После профилирования удаляйте старые cachegrind-файлы: за день их может накопиться несколько гигабайт.