Перейти к содержанию

Отладка PHP-FPM

Отладить PHP-приложение, которое обслуживает PHP-FPM: запрос из браузера или curl останавливается на вашей точке останова.

Предпосылки

  • php-dbgp-adapter в PATH
  • Xdebug, установленный в пуле PHP-FPM
  • уже работающий PHP-FPM

Настройки Xdebug

В том ini, который использует пул FPM:

xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=localhost
xdebug.client_port=9003

После правки перезапустите PHP-FPM:

sudo systemctl restart php-fpm      # или: brew services restart php

Убедитесь, что Xdebug действительно загружен именно в пуле, а не только в CLI-версии PHP — это разные ini:

<?php phpinfo();

Ищите секцию Xdebug со строкой mode => debug.

Конфиг

version = 1
default = "web"

[profiles.web]
adapter = "php"
program = "."

[profiles.web.launch_arguments]
sessionMode = "server"
port = 9003

server — режим для уже работающего: адаптер ждёт, а PHP-запросы подключаются к нему по мере поступления.

Запуск

  1. Поставьте точку останова в файле, до которого запрос дойдёт, — в контроллере, а не в бутстрапе, который отработал давно.

  2. Запустите сессию:

bugsaur gui --project . --break src/Controller/OrderController.php:45
  1. Отправьте запрос:
curl 'http://localhost:8080/orders?id=1'

Что должно произойти

Запрос замирает, отладчик останавливается на строке 45, а curl ждёт ответа, пока вы не продолжите выполнение.

Запросы, отправленные до запуска сессии, отрабатывают как обычно, без отладки. В этом и состоит полезное свойство режима server: сайт продолжает работать, а отладка включается только когда вы этого захотели.

Запросы отваливаются по таймауту, пока вы стоите

Остановленный запрос — это запрос, ответа на который всё ещё ждёт веб-сервер. Nginx или Apache рано или поздно сдадутся:

fastcgi_read_timeout 3600s;

Поднимите таймаут на время отладки или смиритесь с тем, что долгий разбор кончится ошибкой 504 на стороне клиента — на саму сессию отладки это не влияет.

Отлаживать только свои запросы

В общем или нагруженном окружении start_with_request=yes заставляет каждый запрос пытаться подключиться. Используйте триггер:

xdebug.start_with_request=trigger

Тогда отлаживаются только запросы с триггером:

curl -H 'Cookie: XDEBUG_TRIGGER=1' 'http://localhost:8080/orders?id=1'

Браузерные расширения для Xdebug ставят эту куку за вас.

Если не работает

Симптом Что делать
Ничего не останавливается запрос ушёл до старта сессии — отправьте ещё один
Не подключается вообще никогда Xdebug не загружен в FPM-ini; проверьте phpinfo()
Точки останова остаются pending до первого запроса это нормально; после — проверяйте пути
Клиент получает 504 таймаут чтения у веб-сервера — поднимите его
Останавливается в неожиданном файле раньше привязалась точка в общем бутстрап-файле