PHP / Magento Dev Blog

  • Home

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

by Henryk Tews / Thursday, 16 July 2026 / Published in Środowiska

Xdebug 3 changed the configuration approach – instead of many directives, one option xdebug.mode controls all behaviour. Combining Xdebug 3, DDEV and PHPStorm gives a complete environment: step debugger with breakpoints, a profiler generating cachegrind files, and coverage reports for PHPUnit. I show the configuration from scratch and how to analyse profiler results in PHPStorm and QCacheGrind.

Xdebug 3 – modes and configuration

; Xdebug 3 - everything controlled by xdebug.mode
; Possible values (can be combined with commas):
; off        - disabled
; develop    - improved var_dump, stack traces
; coverage   - code coverage for PHPUnit
; debug      - step debugger
; gcstats    - garbage collector statistics
; profile    - profiler (generates cachegrind)
; trace      - function trace

; Minimal configuration for debugging
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

Configuration in DDEV

# DDEV has built-in Xdebug support
ddev xdebug on
ddev xdebug off
ddev xdebug status

# DDEV automatically configures:
# - xdebug.client_host = host.docker.internal
# - xdebug.client_port = 9003
# - Firewall rules for the connection

# Custom configuration: .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

ddev restart   # after changing .ini files

PHPStorm – connection configuration

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

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

# 3. Run > Start Listening for PHP Debug Connections

# 4. Set a breakpoint in PHP code

# 5. Open URL with XDEBUG_SESSION=1 parameter
#    https://magento-shop.ddev.site/?XDEBUG_SESSION=1
#    or use browser extension: Xdebug Helper

# 6. PHPStorm will stop at the breakpoint

Step debugger – commands

# PHPStorm commands during a debug session:
# F8         - Step Over    (execute line, don't enter function)
# F7         - Step Into    (enter function)
# F9         - Resume       (continue to next breakpoint)
# Shift+F8   - Step Out     (exit function)

# Useful when debugging Magento 2:
# - Watches: add PHP expressions to observe
# - Evaluate: execute any PHP expression in current context
# - Variables panel: view all variables

# Conditional breakpoint (right-click breakpoint):
# $order->getGrandTotal() > 1000.0

Profiler – performance analysis

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

# Trigger profiling via URL parameter:
# https://magento-shop.ddev.site/catalog/category/view/id/3?XDEBUG_PROFILE=1

# Copy file from container:
ddev exec ls /var/www/html/xdebug/profiles/
ddev exec cat /var/www/html/xdebug/profiles/cachegrind.out.42 > ./cachegrind.out.42

Cachegrind analysis in PHPStorm

# PHPStorm: Tools > Analyze Xdebug Profiler Snapshot
# Open cachegrind.out.XX file

# PHPStorm Profiler views:
# - Execution Statistics: function list with self and total time
# - Call Tree: call tree with times
# - Flame Graph: hot spot visualisation (PHPStorm 2023+)

# What to look for:
# - Self time: time in this function only (without called functions)
# - Total time: total time including calls
# - Calls: call count - 10000 calls * 0.1ms = 1s!

# Typical hot spots in Magento 2:
# - \Magento\Framework\App\Config\ScopeConfigInterface::getValue
#   (too many calls - cache config in your service)
# - \Magento\Framework\Interception\Interceptor::__callPlugins
#   (too many around plugins)
# - Collections without setPageSize()
#   (loading entire table)

Code coverage in PHPUnit

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

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

# Open coverage-report/index.html in browser
# PHPStorm: Run > Show Code Coverage Data
#           Load coverage.xml for inline coverage in editor

Summary

Xdebug 3 with DDEV is a one-command installation with zero manual IP configuration. Mode debug for the step debugger, profile for performance analysis, coverage for tests. PHPStorm with PHPStorm Profiler and Flame Graph lets you find hot spots quickly. In Magento 2 the most common performance issues are too many ScopeConfig::getValue calls, collections without a limit, and excessive around plugins.

About Henryk Tews

© 2026 Created by

TOP
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 Always active
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.
  • Manage options
  • Manage services
  • Manage {vendor_count} vendors
  • Read more about these purposes
Zobacz preferencje
  • {title}
  • {title}
  • {title}