UK

Налагодження з 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-debugger bin/jumphp один раз збирає образ docker/desktop-phpdebugger на основі десктопного образу, який лишається без нього.
  • На async-рантаймі (PHP 8.6) виводиться повідомлення «PHP Debugger does not run on PHP 8.6 (async runtime): Xdebug is used», і працює Xdebug.

Налагодження вручну в IDE

  1. Точка зупину: клацніть у полях ліворуч від рядка PHP. Праве клацання задає умову (вираз PHP: зупинка лише коли він істинний, наприклад $this->score < 0); Ctrl+F8 ставить точку на позиції курсора. Точки зупину зберігаються для проєкту й рухаються разом зі своїми рядками під час редагування.
  2. Налагодження (Shift+F9): програма запускається й зупиняється на першій точці зупину. Рядок підсвічується, відкривається вікно інструментів Debug.
  3. Дивіться: стек викликів (клацніть кадр, щоб побачити його змінні), змінні у вигляді дерева, що читається на вимогу, watches і поле для обчислення будь-якого виразу PHP в місці зупину.
  4. Зміна значення: подвійне клацання по змінній або F2, введіть вираз PHP (9, "Ada", [1, 2], null) і продовжуйте з новим значенням.
  5. Переміщення: Продовжити F9, Крок з обходом F8, Крок із заходом F7, Крок з виходом Shift+F8, Виконати до курсора Alt+F9, Зупинити.
  6. Винятки: Зупинятися на винятках… (значок попередження вікна 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, зупинися на ній, прочитай змінні й скажи мені, чому так. Виправляй лише після того, як покажеш причину.

Що ШІ робить далі за допомогою наведених інструментів:

  1. знаходить рядок, що додає очко, і ставить там точку зупину, з умовою, якщо рядок виконується на кожному кадрі ($this->ballX < 0);
  2. запускає тест у фоні й чекає зупинки (debug_wait / wait_for_stop);
  3. читає $this->score, $this->scored і стек, щоб побачити, хто викликав цей рядок;
  4. один раз виходить із функції (debug_step step_out), щоб побачити другого викликача: очко зараховується двічі;
  5. перевіряє свою ідею, нічого не редагуючи: присвоює $this->scored значення (debug_set_value / set_variable) і продовжує, щоб переконатися, що рахунок лишається правильним;
  6. і лише тоді редагує код та знову запускає тест, без точки зупину.

Поради

  • Скажіть прямо: «використай налагоджувач». Інакше агент часто повертається до 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.