PHP DBGp¶
Язык: PHP · Транспорт: stdio
php-dbgp-adapter — собственный адаптер Bugsaur, собираемый из того же
workspace. Он заменяет привычный мост DAP↔DBGp и не зависит ни от Node.js, ни от
npm, ни от VS Code, ни от vscode-php-debug. Во время работы участвуют только
bugsaur, php-dbgp-adapter и Xdebug.
Запись каталога:
[adapters.php]
id = "php"
command = "php-dbgp-adapter"
transport = "stdio"
[adapters.php.launch_arguments]
port = 9003
sessionMode = "server"
Обратите внимание: это единственная встроенная запись с умолчаниями в
launch_arguments — PHP-профиль, не назвавший ни port, ни sessionMode,
получит 9003 и server.
Установка¶
Внешнего ничего. make build собирает адаптер рядом с bugsaur:
Почему PHP устроен принципиально иначе¶
Xdebug работает по DBGp, а не по DAP, и делает это наоборот по сравнению с адаптерами других языков: Xdebug подключается к отладчику, а не отладчик запускает программу.
Поэтому php-dbgp-adapter открывает порт и ждёт. Тот, кто запускает PHP —
PHP-FPM, Docker, вызов из CLI, — находится вне управления Bugsaur.
Два следствия:
cwd,envиargsне применяются: передавать их некому;- из тела DAP читаются только три ключа —
port,pathMappings,sessionMode— плюсtestCommandдля отладки теста под курсором.
Три ключа¶
port¶
DBGp-порт, который слушает адаптер; по умолчанию 9003. Он обязан совпадать с
xdebug.client_port в PHP-среде.
Порт на машине один: двум проектам, отлаживающимся одновременно, нужны разные порты.
sessionMode¶
| Значение | Смысл |
|---|---|
server |
PHP уже работает (FPM, встроенный сервер, web-контейнер); адаптер ждёт запросов |
cli |
одноразовый скрипт; адаптер обязан слушать до его старта |
pathMappings¶
Путь контейнера в путь хоста:
Нужен всякий раз, когда PHP работает там, где пути другие, — то есть практически при любой схеме с Docker. Без него точки останова не привязываются, а остановки происходят без исходника. См. Отображения путей.
testCommand¶
Для отладки PHPUnit-теста под курсором профиль передаёт команду, запускающую PHPUnit там, где живёт PHP:
[profiles.docker.launch_arguments]
testCommand = ["docker", "compose", "exec", "-T", "-e", "XDEBUG_TRIGGER=1", "php", "php", "vendor/bin/phpunit"]
Она выполняется после того, как адаптер начал слушать, поэтому к моменту
обратного соединения Xdebug listener уже готов. Переменная XDEBUG_TRIGGER=1
также передаётся внешнему процессу.
Обязательные настройки Xdebug¶
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
client_host — это host.docker.internal из контейнера и localhost, когда PHP
работает на той же машине.
Диагностика¶
| Симптом | Причина | Что делать |
|---|---|---|
php-dbgp-adapter не найден |
каталог сборки не в PATH |
выведите его, см. выше |
| Никто не подключается | запрос ушёл до старта listener'а | повторите запрос после запуска сессии |
| Не подключается вообще никогда | xdebug.mode не debug или выключен start_with_request |
почините ini и перезапустите PHP |
| Порт занят | его держит другой проект | дайте каждому проекту свой порт |
| Останавливается без исходника | pathMappings отсутствует или неверен |
Исходник не найден |
| До первого запроса точки останова pending | спросить пока некого | это нормально — отправьте запрос |