Отладка с Xdebug или PHP Debugger, вручную или с ИИ
В JumPHP IDE есть настоящий пошаговый отладчик: вы останавливаете программу на строке, смотрите переменные, меняете одну из них и идёте дальше шаг за шагом. Он говорит на DBGp, протоколе Xdebug, поэтому может управлять двумя движками:
- Xdebug, классический (по умолчанию);
- PHP Debugger, более новый отладчик DBGp, бесплатный и с открытым кодом, совместимый с настройками Xdebug, с почти нулевыми накладными расходами.
В IDE оба работают одинаково. Отладчик можно также передать ИИ (Claude Code): он сам ставит точки останова, запускает программу, читает переменные и находит ошибку.
Какой движок выбрать
| Xdebug | PHP Debugger | |
|---|---|---|
| В JumPHP | по умолчанию, все рантаймы | десктопный рантайм (PHP 8.2–8.5) |
| Накладные расходы | PHP заметно медленнее | «near-zero overhead when idle», всегда включён, без триггера |
Async-рантайм (PHP 8.6, runtime: async) |
да | нет: используется Xdebug, и IDE сообщает об этом |
| ИИ | MCP-сервер JumPHP (bin/jumphp debug) |
собственный MCP-сервер (dbgp mcp), который видит и вывод скрипта, и предупреждения PHP |
На практике: выбирайте PHP Debugger для повседневной отладки, для долгих запусков (игра на 600 кадров, набор тестов) и для отладки с ИИ. Оставайтесь на Xdebug, если работаете с async-рантаймом (потоки) или вам нужно то, что умеет только Xdebug. В IDE они взаимозаменяемы, так что можно попробовать оба на одном проекте.
На странице PHP Debugger нет никаких цифр бенчмарков: там лишь сказано, что стоимость почти нулевая, пока вы не отлаживаете. Если разница важна, измерьте её на своём проекте.
Выбор движка в IDE
- Кнопка Отладка в шапке (жук рядом с «Запуск»,
Shift+F9) раскрывает меню: Отладка с помощью (Xdebug или PHP Debugger, для этого запуска) и Движок по умолчанию (движок, который используется при обычном щелчке). Щелчок правой кнопкой по кнопке открывает то же меню. - Первый запуск с данным движком собирает образ Docker (около минуты). Последующие стартуют сразу.
- Уведомление сообщает, что программа так и не подключилась к отладчику (завершилась раньше или за 3 минуты ничего не произошло). Причина обычно видна в выводе окна «Запуск».
Выбор движка из терминала
Всё идёт через bin/jumphp, как всегда:
# Xdebug (default)
JUMPHP_XDEBUG=9003 bin/jumphp test pong
# PHP Debugger
JUMPHP_DEBUGGER=php-debugger JUMPHP_XDEBUG=9003 bin/jumphp test pong
JUMPHP_XDEBUG=<port>включает пошаговую отладку: PHP подключается к отладчику, слушающему этот порт вашего компьютера (composer, phpstan иphp -lработают без неё).JUMPHP_DEBUGGER=xdebug|php-debuggerвыбирает движок (по умолчаниюxdebug).- С
php-debuggerbin/jumphpодин раз собирает образdocker/desktop-phpdebuggerна основе десктопного образа, который остаётся без него. - На async-рантайме (PHP 8.6) выводится сообщение «PHP Debugger does not run on PHP 8.6 (async runtime): Xdebug is used», и работает Xdebug.
Отладка вручную в IDE
- Точка останова: щёлкните в полях слева от строки PHP. Правый щелчок задаёт условие (выражение PHP: остановка только когда оно истинно, например
$this->score < 0);Ctrl+F8ставит точку на позиции курсора. Точки останова хранятся для проекта и следуют за своими строками при редактировании. - Отладка (
Shift+F9): программа запускается и останавливается на первой точке останова. Строка подсвечивается, открывается окно инструментов Debug. - Смотрите: стек вызовов (щёлкните кадр, чтобы увидеть его переменные), переменные в виде дерева, читаемого по требованию, watches и поле для вычисления любого выражения PHP в месте остановки.
- Изменение значения: двойной щелчок по переменной или
F2, введите выражение PHP (9,"Ada",[1, 2],null) и продолжайте с новым значением. - Перемещение: Продолжить
F9, Шаг с обходомF8, Шаг с заходомF7, Шаг с выходомShift+F8, Выполнить до курсораAlt+F9, Остановить. - Исключения: Останавливаться на исключениях… (значок предупреждения окна Debug):
*или имена классов (TypeError,App\GameOver). Остановка происходит там, где исключение выброшено, перехвачено оно или нет, с показом самого исключения и его сообщения.
Инспектор при наведении (в следующем обновлении IDE): когда программа остановлена на точке останова, наведите мышь на переменную в редакторе, чтобы получить раскрываемое дерево её значения с кнопками Copy и Edit.
Совет для игр: отлаживайте headless-запуски (test, shot): игра, остановленная внутри окна, зависает, пока вы её не продолжите.
Отладка с ИИ
ИИ отлаживает лучше с отладчиком, чем с var_dump(): он читает реальные значения, по одному вопросу за раз, и ничего не меняет в вашем коде. Доступны два MCP-сервера. Используйте один за раз (оба слушают порт 9003).
1. Сервер JumPHP: bin/jumphp debug
Собственный отладчик IDE как MCP-сервер (работает в Docker, с Xdebug):
claude mcp add jumphp-debug -- bin/jumphp debug
Его инструменты:
| Инструмент | Что делает |
|---|---|
debug_breakpoints |
ставит точки останова файла (lines или {line, condition}), без пути перечисляет их, clear_all |
debug_exceptions |
исключения, останавливающие программу (* = все, [] = никаких) |
debug_wait |
ждёт, пока программа остановится на точке останова или исключении, затем выдаёт место, стек и переменные |
debug_state |
где остановлена, стек, переменные кадра |
debug_step |
step_over, step_into, step_out, run, stop: ждёт следующей остановки |
debug_run_to |
выполняет до строки |
debug_eval |
вычисляет выражение PHP в месте остановки |
debug_variables |
переменные кадра или дочерние элементы одной из них ($this->player, $list[3]) |
debug_set_value |
задаёт переменной новое значение (выражение PHP) |
Пути указываются относительно проекта. Claude запускает программу сам, в фоне, с JUMPHP_XDEBUG=9003, затем вызывает debug_wait.
2. Сервер PHP Debugger: dbgp mcp
PHP Debugger поставляет собственный MCP-сервер в небольшой программе dbgp (лицензия MIT; Linux и macOS, amd64 и arm64; Windows amd64).
# install (macOS / Linux)
curl -fsSL https://github.com/php-debugger/dbgp-client/releases/latest/download/install.sh | sh
dbgp -version
# for this project / for all your projects
claude mcp add dbgp -- dbgp mcp
claude mcp add --scope user dbgp -- dbgp mcp
В Claude Code команда /mcp показывает, что он подключён. Его инструменты под именами из документации PHP Debugger:
- соединение:
status,listen,unlisten,sessions,wait_for_session,detach; - точки останова:
add_breakpoint,remove_breakpoint,breakpoints; - выполнение:
continue,wait_for_stop,stop; - просмотр:
stack,variables,variable,variable_value,source,output,warnings; - действия:
eval,set_variable; - Docker / удалённо:
add_path_mapping,path_mappings.
Полезные флаги (dbgp mcp -h показывает все): -php-port PORT (порт, к которому подключается PHP, по умолчанию 9003), -mcp-port PORT, -idekey KEY, -map LOCAL=REMOTE (сопоставление путей, можно повторять) и -no-eval, запрещающий eval, set_variable и условные точки останова: ИИ может только смотреть. Он не скрывает значения, поэтому пароли и ключи остаются ему видны.
Через bin/jumphp команда JUMPHP_DEBUGGER=php-debugger bin/jumphp debug сама запускает dbgp mcp (на вашем компьютере должен быть установлен dbgp). Затем запустите программу с тем же движком:
JUMPHP_DEBUGGER=php-debugger JUMPHP_XDEBUG=9003 bin/jumphp test pong
Пример сеанса
Вы, Claude Code:
Счёт в игре
pongрастёт на 2 вместо 1, когда мяч пролетает мимо левой ракетки. Используй отладчик, а не var_dump. Поставь точку останова там, где увеличивается счёт (смотри вPlayScene), запустиbin/jumphp test pongсJUMPHP_XDEBUG=9003, остановись на ней, прочитай переменные и скажи мне, почему так. Исправляй только после того, как покажешь причину.
Что ИИ делает дальше с помощью инструментов выше:
- находит строку, добавляющую очко, и ставит там точку останова, с условием, если строка выполняется на каждом кадре (
$this->ballX < 0); - запускает тест в фоне и ждёт остановки (
debug_wait/wait_for_stop); - читает
$this->score,$this->scoredи стек, чтобы увидеть, кто вызвал эту строку; - один раз выходит из функции (
debug_stepstep_out), чтобы увидеть второго вызывающего: очко засчитывается дважды; - проверяет свою идею, ничего не правя: присваивает
$this->scoredзначение (debug_set_value/set_variable) и продолжает, чтобы убедиться, что счёт остаётся верным; - и только потом правит код и снова запускает тест, без точки останова.
Советы
- Скажите прямо: «используй отладчик». Иначе агент часто возвращается к
var_dump(). - Дайте ему команду, показывающую ошибку, то, чего вы ждёте, и место, где подозреваете причину.
- Маленькие шаги: несколько
step_over, затем просмотр. Условная точка останова ($enemy->hp <= 0) лучше, чем прохождение 600 кадров. - Пусть он читает переменные и вычисляет выражения: никаких
var_dump(), никакихecho, нечего убирать после. - Предпочитайте headless-запуски (
test,shot,php) окну. - Секреты: ИИ видит каждую прочитанную переменную (пароли, токены, ключи API). Отлаживайте на тестовых данных и используйте
-no-evalсdbgp, если не хотите, чтобы он выполнял код в вашей программе. - Не оставляйте MCP-сервер отладчика подключённым в проекте, где вы не отлаживаете: удалите его командой
claude mcp remove.
Устранение неполадок
Ничего не останавливается / «did not connect».
Слушает ли порт какой-нибудь отладчик (окно Debug в IDE или MCP-сервер)? Программа должна быть запущена с JUMPHP_XDEBUG=<port> и тем же движком, что и слушающий.
Порт уже занят.
Два слушателя на 9003: IDE и bin/jumphp debug (или dbgp mcp), либо две IDE. Остановите один или возьмите другой порт: JUMPHP_DEBUG_PORT=9010 bin/jumphp debug с JUMPHP_XDEBUG=9010, или dbgp -php-port 9010 mcp.
Точка останова никогда не срабатывает.
Она стоит на строке без кода (комментарий, пустая строка, закрывающая скобка) или в файле, который программа никогда не загружает. Вызовите debug_state / посмотрите стек, чтобы увидеть, где программа. С -map или в IDE пути должны совпадать (ниже).
Пути в Docker.
bin/jumphp монтирует ваш проект в /workspace в контейнере: отладчик сообщает file:///workspace/.... IDE и bin/jumphp debug сами сопоставляют это с файлами проекта, а указываемые вами пути относительны проекта. С одним dbgp mcp сопоставьте папки: dbgp mcp -map /home/you/project=/workspace.
PHP 8.6 (async-рантайм).
PHP Debugger там не работает: используется Xdebug. Чтобы пользоваться PHP Debugger, отлаживайте на рантайме по умолчанию (PHP 8.5) или уберите runtime: async на время сеанса.
Браузерные игры.
Отладчик работает на десктопном рантайме. В браузере воспроизведите ошибку через bin/jumphp test или shot на десктопе.
См. также Писать код, запускать и тестировать, Claude в IDE и IDE Remote.