Debugowanie z Xdebug lub PHP Debugger, ręcznie albo z AI
JumPHP IDE ma prawdziwy debugger krokowy: zatrzymujesz program na linii, oglądasz zmienne, zmieniasz jedną z nich i idziesz dalej krok po kroku. Mówi on DBGp, protokołem Xdebug, więc może obsługiwać dwa silniki:
- Xdebug, klasyczny (domyślny);
- PHP Debugger, nowszy debugger DBGp, darmowy i open source, zgodny z ustawieniami Xdebug, z narzutem bliskim zeru.
W IDE oba działają tak samo. Debugger możesz też oddać AI (Claude Code): sam ustawia punkty przerwania, uruchamia program, czyta zmienne i znajduje błąd.
Który silnik wybrać
| Xdebug | PHP Debugger | |
|---|---|---|
| W JumPHP | domyślny, wszystkie runtime'y | runtime desktopowy (PHP 8.2 do 8.5) |
| Narzut | PHP działa wyraźnie wolniej | „near-zero overhead when idle", zawsze włączony, bez wyzwalacza |
Runtime async (PHP 8.6, runtime: async) |
tak | nie: używany jest Xdebug, a IDE o tym informuje |
| AI | serwer MCP JumPHP (bin/jumphp debug) |
własny serwer MCP (dbgp mcp), który widzi też wyjście skryptu i ostrzeżenia PHP |
W praktyce: wybierz PHP Debugger do codziennego debugowania, długich uruchomień (gra grająca 600 klatek, zestaw testów) i debugowania z AI. Zostań przy Xdebug, jeśli pracujesz z runtime async (wątki) lub potrzebujesz czegoś, co potrafi tylko Xdebug. W IDE oba są wymienne, więc możesz wypróbować oba na tym samym projekcie.
Strona PHP Debuggera nie podaje żadnych wyników pomiarów: stwierdza tylko, że koszt jest bliski zeru, dopóki nie debugujesz. Jeśli różnica ma dla ciebie znaczenie, zmierz ją na własnym projekcie.
Wybór silnika w IDE
- Przycisk Debuguj w nagłówku (robak obok Uruchom,
Shift+F9) rozwija menu: Debuguj za pomocą (Xdebug lub PHP Debugger, dla tego uruchomienia) i Silnik domyślny (silnik używany odtąd przy zwykłym kliknięciu). Kliknięcie prawym przyciskiem otwiera to samo menu. - Pierwsze uruchomienie z danym silnikiem buduje obraz Dockera (około minuty). Kolejne startują od razu.
- Powiadomienie informuje, gdy program nigdy nie połączył się z debuggerem (zakończył się wcześniej albo nic po 3 minutach). Powód zwykle widać w wyjściu okna Uruchom.
Wybór silnika z terminala
Wszystko idzie przez bin/jumphp, jak zawsze:
# 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>włącza debugowanie krokowe: PHP łączy się z debuggerem nasłuchującym na tym porcie twojego komputera (composer, phpstan iphp -ldziałają bez niego).JUMPHP_DEBUGGER=xdebug|php-debuggerwybiera silnik (domyślniexdebug).- Z
php-debuggerbin/jumphpbuduje jednorazowo obrazdocker/desktop-phpdebuggerna bazie obrazu desktopowego, który pozostaje bez niego. - Na runtime async (PHP 8.6) wyświetlany jest komunikat „PHP Debugger does not run on PHP 8.6 (async runtime): Xdebug is used" i działa Xdebug.
Debugowanie ręczne w IDE
- Punkt przerwania: kliknij w rynnę po lewej stronie linii PHP. Prawy przycisk pozwala ustawić warunek (wyrażenie PHP: zatrzymanie tylko gdy prawdziwe, np.
$this->score < 0);Ctrl+F8ustawia punkt przy kursorze. Punkty przerwania są zapamiętywane dla projektu i podążają za swoimi liniami podczas edycji. - Debuguj (
Shift+F9): program działa i zatrzymuje się na pierwszym punkcie przerwania. Linia jest zaznaczona i otwiera się okno narzędzia Debug. - Oglądaj: stos wywołań (kliknij ramkę, by zobaczyć jej zmienne), zmienne jako drzewo czytane na żądanie, watches i pole do obliczania dowolnego wyrażenia PHP w miejscu zatrzymania.
- Zmiana wartości: dwuklik na zmiennej lub
F2, wpisz wyrażenie PHP (9,"Ada",[1, 2],null) i kontynuuj z nową wartością. - Poruszanie się: Wznów
F9, Krok przezF8, Krok do wnętrzaF7, Krok na zewnątrzShift+F8, Uruchom do kursoraAlt+F9, Zatrzymaj. - Wyjątki: Zatrzymuj na wyjątkach… (ikona ostrzeżenia w oknie Debug):
*lub nazwy klas (TypeError,App\GameOver). Zatrzymuje się tam, gdzie wyjątek jest rzucany, złapany czy nie, i pokazuje który, wraz z komunikatem.
Inspektor po najechaniu myszą (w następnej aktualizacji IDE): gdy program jest zatrzymany na punkcie przerwania, najedź myszą na zmienną w edytorze, by zobaczyć rozwijane drzewo jej wartości z przyciskami Copy i Edit.
Wskazówka dla gier: debuguj uruchomienia headless (test, shot): gra zatrzymana w oknie zawiesza się, dopóki jej nie wznowisz.
Debugowanie z AI
AI lepiej debuguje z debuggerem niż z var_dump(): czyta prawdziwe wartości, jedno pytanie naraz, i niczego nie zmienia w twoim kodzie. Dostępne są dwa serwery MCP. Używaj jednego naraz (oba nasłuchują na porcie 9003).
1. Serwer JumPHP: bin/jumphp debug
Własny debugger IDE jako serwer MCP (działa w Dockerze, z Xdebug):
claude mcp add jumphp-debug -- bin/jumphp debug
Jego narzędzia:
| Narzędzie | Co robi |
|---|---|
debug_breakpoints |
ustawia punkty przerwania pliku (lines lub {line, condition}), bez ścieżki wypisuje je, clear_all |
debug_exceptions |
wyjątki zatrzymujące program (* = wszystkie, [] = żadne) |
debug_wait |
czeka, aż program zatrzyma się na punkcie przerwania lub wyjątku, po czym podaje miejsce, stos i zmienne |
debug_state |
gdzie się zatrzymał, stos, zmienne ramki |
debug_step |
step_over, step_into, step_out, run, stop: czeka na następne zatrzymanie |
debug_run_to |
uruchamia do wskazanej linii |
debug_eval |
oblicza wyrażenie PHP w miejscu zatrzymania |
debug_variables |
zmienne ramki lub elementy potomne jednej z nich ($this->player, $list[3]) |
debug_set_value |
nadaje zmiennej nową wartość (wyrażenie PHP) |
Ścieżki są względne wobec projektu. Claude uruchamia program sam, w tle, z JUMPHP_XDEBUG=9003, a następnie wywołuje debug_wait.
2. Serwer PHP Debuggera: dbgp mcp
PHP Debugger dostarcza własny serwer MCP w małym programie dbgp (licencja MIT; Linux i macOS, amd64 i 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
W Claude Code /mcp pokazuje, że jest połączony. Jego narzędzia, pod nazwami z dokumentacji PHP Debuggera:
- połączenie:
status,listen,unlisten,sessions,wait_for_session,detach; - punkty przerwania:
add_breakpoint,remove_breakpoint,breakpoints; - uruchamianie:
continue,wait_for_stop,stop; - oglądanie:
stack,variables,variable,variable_value,source,output,warnings; - działanie:
eval,set_variable; - Docker / zdalnie:
add_path_mapping,path_mappings.
Przydatne flagi (dbgp mcp -h pokazuje wszystkie): -php-port PORT (port, z którym łączy się PHP, domyślnie 9003), -mcp-port PORT, -idekey KEY, -map LOCAL=REMOTE (mapowanie ścieżek, można powtarzać) oraz -no-eval, które zabrania eval, set_variable i warunkowych punktów przerwania: AI może wtedy tylko patrzeć. Nie ukrywa ono wartości, więc hasła i klucze pozostają dla niego widoczne.
Przez bin/jumphp polecenie JUMPHP_DEBUGGER=php-debugger bin/jumphp debug uruchamia dbgp mcp za ciebie (wymaga zainstalowanego dbgp na twoim komputerze). Następnie uruchom program z tym samym silnikiem:
JUMPHP_DEBUGGER=php-debugger JUMPHP_XDEBUG=9003 bin/jumphp test pong
Przykładowa sesja
Ty, do Claude Code:
Wynik w grze
pongrośnie o 2 zamiast o 1, gdy piłka mija lewą paletkę. Użyj debuggera, nie var_dump. Ustaw punkt przerwania tam, gdzie wynik jest zwiększany (zajrzyj doPlayScene), uruchombin/jumphp test pongzJUMPHP_XDEBUG=9003, zatrzymaj się na nim, odczytaj zmienne i powiedz mi dlaczego. Napraw dopiero po tym, jak pokażesz mi przyczynę.
Co AI wtedy robi, za pomocą powyższych narzędzi:
- znajduje linię dodającą punkt i ustawia tam punkt przerwania, z warunkiem, jeśli linia wykonuje się w każdej klatce (
$this->ballX < 0); - uruchamia test w tle i czeka na zatrzymanie (
debug_wait/wait_for_stop); - odczytuje
$this->score,$this->scoredi stos, by zobaczyć, kto wywołał tę linię; - raz wychodzi z funkcji (
debug_stepstep_out), by zobaczyć drugiego wywołującego: punkt jest liczony dwa razy; - sprawdza swój pomysł, niczego nie edytując: nadaje
$this->scoredwartość (debug_set_value/set_variable) i kontynuuje, by zobaczyć, że wynik pozostaje poprawny; - dopiero wtedy edytuje kod i ponownie uruchamia test, bez punktu przerwania.
Wskazówki
- Powiedz to wprost: „użyj debuggera". Inaczej agent często wraca do
var_dump(). - Podaj polecenie pokazujące błąd, czego oczekujesz i gdzie go podejrzewasz.
- Małe kroki: kilka
step_over, potem oglądanie. Warunkowy punkt przerwania ($enemy->hp <= 0) jest lepszy niż przechodzenie przez 600 klatek. - Pozwól mu czytać zmienne i obliczać wyrażenia: żadnych
var_dump(), żadnychecho, nic do sprzątania. - Wybieraj uruchomienia headless (
test,shot,php) zamiast okna. - Sekrety: AI widzi każdą zmienną, którą czyta (hasła, tokeny, klucze API). Debuguj na danych testowych i użyj
-no-evalzdbgp, jeśli nie chcesz, by wykonywało kod w twoim programie. - Nie zostawiaj serwera MCP debuggera podłączonego w projekcie, w którym nie debugujesz: usuń go poleceniem
claude mcp remove.
Rozwiązywanie problemów
Nic się nie zatrzymuje / „did not connect".
Czy jakiś debugger nasłuchuje na tym porcie (okno Debug w IDE albo serwer MCP)? Program musi być uruchomiony z JUMPHP_XDEBUG=<port> i tym samym silnikiem co nasłuchujący.
Port jest już zajęty.
Dwa nasłuchujące na 9003: IDE i bin/jumphp debug (albo dbgp mcp), albo dwa IDE. Zatrzymaj jedno lub użyj innego portu: JUMPHP_DEBUG_PORT=9010 bin/jumphp debug z JUMPHP_XDEBUG=9010, albo dbgp -php-port 9010 mcp.
Punkt przerwania nigdy nie jest osiągany.
Jest na linii bez kodu (komentarz, pusta linia, zamykający nawias klamrowy) lub w pliku, którego program nigdy nie ładuje. Wywołaj debug_state / spójrz na stos, by zobaczyć, gdzie jest. Przy -map lub w IDE: ścieżki muszą się zgadzać (patrz niżej).
Ścieżki w Dockerze.
bin/jumphp montuje twój projekt w /workspace w kontenerze: debugger podaje file:///workspace/.... IDE i bin/jumphp debug same mapują to na pliki projektu, a podawane ścieżki są względne wobec projektu. Samo dbgp mcp wymaga mapowania katalogów: dbgp mcp -map /home/you/project=/workspace.
PHP 8.6 (runtime async).
PHP Debugger tam nie działa: używany jest Xdebug. Aby użyć PHP Debuggera, debuguj na domyślnym runtime (PHP 8.5) albo na czas sesji usuń runtime: async.
Gry w przeglądarce.
Debugger działa na runtime desktopowym. W przeglądarce odtwórz błąd za pomocą bin/jumphp test lub shot na desktopie.
Zobacz też Programowanie, uruchamianie i testy, Claude w IDE oraz IDE Remote.