PHP / Magento Dev Blog

  • Publikacje
  • O autorze
  • Kontakt

Xdebug 3 + DDEV + PHPStorm – debugowanie, profiling, flamegraph

by Henryk Tews / czwartek, 16 lipca 2026 / Opublikowano w Środowiska

Xdebug 3 zmienił sposób konfiguracji – zamiast wielu dyrektyw jedna opcja xdebug.mode steruje całym zachowaniem. Połączenie Xdebug 3, DDEV i PHPStorm daje kompletne środowisko: step debugger z breakpointami, profiler który generuje cachegrind, i coverage raporty dla PHPUnit. Pokażę konfigurację od zera i jak analizować wyniki profilera w PHPStorm i QCacheGrind.

Xdebug 3 – tryby i konfiguracja

; Xdebug 3 - wszystko sterowane przez xdebug.mode
; Możliwe wartości (można łączyć przecinkami):
; off        - wyłączony
; develop    - var_dump ulepszony, stack traces
; coverage   - code coverage dla PHPUnit
; debug      - step debugger
; gcstats    - garbage collector statistics
; profile    - profiler (generuje cachegrind)
; trace      - function trace

; Minimalna konfiguracja dla debugowania
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.client_host = host.docker.internal
xdebug.client_port = 9003
xdebug.log = /var/log/xdebug.log
xdebug.log_level = 7

Konfiguracja w DDEV

# DDEV ma wbudowane wsparcie dla Xdebug
# Włącz/wyłącz jedną komendą:
ddev xdebug on
ddev xdebug off

# Sprawdź status
ddev xdebug status

# DDEV automatycznie konfiguruje:
# - xdebug.client_host = host.docker.internal
# - xdebug.client_port = 9003
# - Firewall rules dla połączenia

# Custom konfiguracja: .ddev/php/xdebug.ini
cat .ddev/php/xdebug.ini
# xdebug.mode = debug,profile
# xdebug.start_with_request = trigger
# xdebug.output_dir = /var/www/html/xdebug
# xdebug.profiler_output_name = cachegrind.out.%p.%H

# Po zmianie pliku .ini:
ddev restart

PHPStorm – konfiguracja połączenia

# 1. PHPStorm: Settings > PHP > Debug
#    Debug port: 9003
#    Zaznacz: "Can accept external connections"

# 2. Settings > PHP > Servers
#    Name: ddev
#    Host: magento-shop.ddev.site
#    Port: 443
#    Debugger: Xdebug
#    Use path mappings: TAK
#    /var/www/html -> /Users/henryk/projects/magento-shop

# 3. Run > Start Listening for PHP Debug Connections
#    (lub ikona telefonu w toolbarze)

# 4. Ustaw breakpoint w kodzie PHP

# 5. Otwórz URL w przeglądarce z parametrem XDEBUG_SESSION=1
#    https://magento-shop.ddev.site/?XDEBUG_SESSION=1
#    lub użyj rozszerzenia przeglądarki: Xdebug Helper

# 6. PHPStorm zatrzyma się na breakpoincie

Step debugger – komendy

# Komendy w PHPStorm podczas sesji debugowania:
# F8  - Step Over    (wykonaj linię, nie wchodź do funkcji)
# F7  - Step Into    (wejdź do funkcji)
# F9  - Resume       (kontynuuj do następnego breakpointa)
# Shift+F8 - Step Out (wyjdź z funkcji)

# Przydatne podczas debugowania Magento 2:
# - Watches: dodaj wyrażenia PHP do obserwowania
# - Evaluate: wykonaj dowolne wyrażenie PHP w kontekście
# - Variables panel: podgląd wszystkich zmiennych

# Conditional breakpoint (prawy klik na breakpoincie):
# $order->getGrandTotal() > 1000.0

# Breakpoint w metodzie konkretnej klasy:
# Class: Magento\Sales\Model\Order
# Method: place

Profiler – analiza wydajności

# .ddev/php/xdebug.ini - tryb profilowania
# xdebug.mode = profile
# xdebug.output_dir = /var/www/html/xdebug/profiles
# xdebug.profiler_output_name = cachegrind.out.%p

# Wyzwól profilowanie przez parametr URL:
# https://magento-shop.ddev.site/catalog/category/view/id/3?XDEBUG_PROFILE=1

# Lub wyzwalanie przez trigger (wydajniejsze):
# xdebug.start_with_request = trigger
# Plik cachegrind.out.XXXX pojawi się w katalogu output_dir

# Skopiuj plik z kontenera:
ddev exec ls /var/www/html/xdebug/profiles/
ddev exec cat /var/www/html/xdebug/profiles/cachegrind.out.42 > ./cachegrind.out.42

Analiza cachegrind w PHPStorm

# PHPStorm: Tools > Analyze Xdebug Profiler Snapshot
# Otwórz plik cachegrind.out.XX

# Widoki w PHPStorm Profiler:
# - Execution Statistics: lista funkcji z czasem własnym i łącznym
# - Call Tree: drzewo wywołań z czasami
# - Flame Graph: wizualizacja hot spots (PHPStorm 2023+)

# Na co zwracać uwagę:
# - Self time: czas spędzony tylko w tej funkcji (bez wywołanych)
# - Total time: czas całkowity z wywołaniami
# - Calls: liczba wywołań - 10000 wywołań * 0.1ms = 1s!

# Typowe hot spots w Magento 2:
# - \Magento\Framework\App\Config\ScopeConfigInterface::getValue
#   (za dużo wywołań - cache konfigurację w serwisie)
# - \Magento\Framework\Interception\Interceptor::__callPlugins
#   (za dużo around plugins)
# - Kolekcje bez setPageSize()
#   (ładowanie całej tabeli)

Code coverage w PHPUnit

# .ddev/php/xdebug.ini
# xdebug.mode = coverage

# phpunit.xml
# <coverage>
#   <include>
#     <directory>./app/code/Vendor</directory>
#   </include>
#   <report>
#     <html outputDirectory="coverage-report"/>
#     <clover outputFile="coverage.xml"/>
#   </report>
# </coverage>

ddev exec vendor/bin/phpunit \
    --coverage-html coverage-report \
    --coverage-clover coverage.xml \
    app/code/Vendor/Module/Test/Unit

# Otwórz coverage-report/index.html w przeglądarce
# PHPStorm: Run > Show Code Coverage Data
#           Załaduj coverage.xml dla inline coverage w edytorze

Podsumowanie

Xdebug 3 z DDEV to instalacja jedną komendą i zero ręcznej konfiguracji IP. Tryb debug do step debuggera, profile do analizy wydajności, coverage do testów. PHPStorm z PHPStorm Profiler i Flame Graph pozwala szybko znaleźć hot spoty. W Magento 2 najczęstsze problemy wydajności to zbyt wiele wywołań ScopeConfig::getValue, kolekcje bez limitu i nadmierna liczba around plugins.

About Henryk Tews

Co możesz przeczytać następne

Kubernetes dla PHP developera – kubectl debugging, Deployment YAML, HPA, troubleshooting
Docker od zera – Dockerfile, nginx, docker-compose, Xdebug 3.x
GitHub Actions – pipeline dla PHP, matrix testów, deploy na staging przez SSH
  • Publikacje
  • O autorze
  • Kontakt

© 2026 Created by

GÓRA
Zarządzaj zgodą
Aby zapewnić jak najlepsze wrażenia, korzystamy z technologii, takich jak pliki cookie, do przechowywania i/lub uzyskiwania dostępu do informacji o urządzeniu. Zgoda na te technologie pozwoli nam przetwarzać dane, takie jak zachowanie podczas przeglądania lub unikalne identyfikatory na tej stronie. Brak wyrażenia zgody lub wycofanie zgody może niekorzystnie wpłynąć na niektóre cechy i funkcje.
Funkcjonalne Zawsze aktywne
Przechowywanie lub dostęp do danych technicznych jest ściśle konieczny do uzasadnionego celu umożliwienia korzystania z konkretnej usługi wyraźnie żądanej przez subskrybenta lub użytkownika, lub wyłącznie w celu przeprowadzenia transmisji komunikatu przez sieć łączności elektronicznej.
Preferencje
Przechowywanie lub dostęp techniczny jest niezbędny do uzasadnionego celu przechowywania preferencji, o które nie prosi subskrybent lub użytkownik.
Statystyka
Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do celów statystycznych. Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do anonimowych celów statystycznych. Bez wezwania do sądu, dobrowolnego podporządkowania się dostawcy usług internetowych lub dodatkowych zapisów od strony trzeciej, informacje przechowywane lub pobierane wyłącznie w tym celu zwykle nie mogą być wykorzystywane do identyfikacji użytkownika.
Marketing
Przechowywanie lub dostęp techniczny jest wymagany do tworzenia profili użytkowników w celu wysyłania reklam lub śledzenia użytkownika na stronie internetowej lub na kilku stronach internetowych w podobnych celach marketingowych.
  • Zarządzaj opcjami
  • Zarządzaj serwisami
  • Zarządzaj {vendor_count} dostawcami
  • Przeczytaj więcej o tych celach
Zobacz preferencje
  • {title}
  • {title}
  • {title}