Xdebug — ключевой инструмент для PHP-разработчиков, предоставляющий возможности пошаговой отладки, профилирования и покрытия кода. Хотя у var_dump и логирования есть своё место, ничто не сравнится с полноценной отладкой, когда нужно понять сложные потоки выполнения кода. Это руководство рассматривает настройку и эффективное использование Xdebug с точки зрения senior-разработчика.
Зачем нужен Xdebug
Xdebug преобразует разработку на PHP:
- Пошаговая отладка: устанавливайте точки останова, инспектируйте переменные, проходите код шаг за шагом
- Профилирование: находите узкие места производительности по детальным данным таймингов
- Трассировки стека: получайте информативные трассировки ошибок с локальными переменными
- Покрытие кода: точно измеряйте покрытие тестами
- Интеграция с IDE: работает с PhpStorm, VS Code и другими редакторами
Предупреждение: никогда не включайте Xdebug на production-серверах — он существенно влияет на производительность.
Установка
Стандартная установка
# С использованием pecl
pecl install xdebug
# На Ubuntu/Debian
sudo apt install php-xdebug
# На CentOS/RHEL
sudo dnf install php-pecl-xdebug
Установка в Docker
Добавьте в ваш development Dockerfile:
FROM php:8.2-fpm
# Установить Xdebug
RUN pecl install xdebug \
&& docker-php-ext-enable xdebug
# Скопировать конфигурацию Xdebug
COPY xdebug.ini $PHP_INI_DIR/conf.d/xdebug.ini
Создайте xdebug.ini:
[xdebug]
zend_extension=xdebug
; Enable step debugging
xdebug.mode=debug
xdebug.start_with_request=trigger
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.idekey=PHPSTORM
; Optionally enable profiling
; xdebug.mode=debug,profile
; xdebug.output_dir=/var/www/html/profiles
Для Docker Compose обеспечьте корректную настройку сети:
version: '3.8'
services:
php:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- ./:/var/www/html
environment:
- PHP_IDE_CONFIG=serverName=docker
extra_hosts:
- "host.docker.internal:host-gateway"
Режимы конфигурации Xdebug 3
Xdebug 3 использует режимы для управления функциями. Задаются через xdebug.mode:
| Режим | Описание |
|---|
off | Ничего не включено (по умолчанию) |
develop | Вспомогательные средства для разработки (улучшения var_dump) |
debug | Пошаговая отладка |
profile | Профилирование |
coverage | Покрытие кода |
trace | Трассировка функций |
Комбинируйте режимы через запятую:
xdebug.mode=debug,profile,coverage
Настройка пошаговой отладки
Конфигурация для отладки
Создайте или отредактируйте xdebug.ini:
[xdebug]
zend_extension=xdebug
xdebug.mode=debug
xdebug.start_with_request=trigger
xdebug.client_host=127.0.0.1
xdebug.client_port=9003
xdebug.idekey=PHPSTORM
xdebug.log=/tmp/xdebug.log
Методы триггера
При startwithrequest=trigger отладка запускается, когда:
- GET/POST-параметр:
?XDEBUGSESSIONSTART=PHPSTORM - Cookie:
XDEBUG_SESSION=PHPSTORM - Расширение браузера: Xdebug Helper для Chrome/Firefox
Настройка PhpStorm
- Перейдите в Settings → PHP → Debug
- Установите Debug port в
9003 - Включите "Can accept external connections"
- Перейдите в Settings → PHP → Servers
- Добавьте сервер с сопоставлением путей для Docker:
- Name: docker - Host: localhost - Port: 80 - Debugger: Xdebug - Path mappings: /local/path → /var/www/html
Настройка VS Code
Установите расширение PHP Debug, затем создайте .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html": "${workspaceFolder}"
}
},
{
"name": "Launch currently open script",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 9003
}
]
}
Отладка CLI-скриптов
Для PHP-скриптов командной строки:
# Установить переменную окружения
export XDEBUG_SESSION=1
php artisan my:command
# Или inline
XDEBUG_SESSION=1 php script.php
Профилирование производительности
Включение профилирования
Настройте профилирование по запросу:
[xdebug]
zend_extension=xdebug
xdebug.mode=profile
xdebug.start_with_request=trigger
xdebug.output_dir=/var/www/html/profiles
xdebug.profiler_output_name=cachegrind.out.%p.%t
Запускайте профилирование, добавляя ?XDEBUG_PROFILE к любому URL:
http://localhost/api/users?XDEBUG_PROFILE
Анализ данных профиля
Файлы профиля используют формат cachegrind. Анализируйте с помощью:
KCachegrind (Linux/macOS):
# Установить
sudo apt install kcachegrind # Ubuntu
brew install qcachegrind # macOS
# Открыть профиль
kcachegrind profiles/cachegrind.out.12345
Webgrind (веб-интерфейс):
# Клонировать webgrind
git clone https://github.com/jokkedk/webgrind.git
# Направить веб-сервер на папку webgrind
# Открыть через http://localhost/webgrind
Чтение вывода профайлера
Ключевые метрики для анализа:
- Self Time: время, потраченное внутри самой функции
- Inclusive Time: время с учётом вызванных функций
- Call Count: количество вызовов функции
Сфокусируйтесь на:
- функциях с высоким self time (цели для оптимизации)
- функциях, вызываемых чрезмерно часто (возможные N+1 запросы)
- неожиданных вызовах функций (для отладки)
Лучшие практики профилирования
// Профилировать конкретные участки кода
xdebug_start_profiling();
// Ваш код здесь
$result = expensiveOperation();
xdebug_stop_profiling();
Покрытие кода
Настройка для покрытия
[xdebug]
xdebug.mode=coverage
Интеграция с PHPUnit
<!--phpunit.xml-->
<phpunit>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./app</directory>
</include>
<exclude>
<directory>./vendor</directory>
</exclude>
<report>
<html outputDirectory="coverage-report"/>
<text outputFile="coverage.txt"/>
</report>
</coverage>
</phpunit>
Запуск с покрытием:
php artisan test --coverage
# или
./vendor/bin/phpunit --coverage-html coverage-report
Вспомогательные средства для разработки
Улучшенный var_dump
При xdebug.mode=develop:
$data = ['users' => [
['name' => 'John', 'email' => '[email protected]'],
['name' => 'Jane', 'email' => '[email protected]'],
]];
var_dump($data); // Теперь показывает цветной, форматированный вывод
Трассировки стека
Xdebug автоматически улучшает трассировки стека ошибок:
function level3() {
throw new Exception("Something went wrong");
}
function level2() {
level3();
}
function level1() {
level2();
}
level1(); // Трассировка стека показывает все уровни с локальными переменными
Устранение неполадок
Проверка установки
<?php
phpinfo(); // Найдите раздел Xdebug
// или
php -v // Должно показывать "with Xdebug"
Проверка конфигурации
php -i | grep xdebug
Распространённые проблемы
Connection refused:
- убедитесь, что IDE слушает правильный порт
- проверьте правила firewall
- убедитесь, что
client_host указан корректно (для Docker используйте host.docker.internal)
Отладка не запускается:
- проверьте, что
xdebug.mode включает debug - проверьте метод триггера (cookie, GET-параметр)
- изучите лог Xdebug:
xdebug.log=/tmp/xdebug.log
Проблемы с сопоставлением путей:
- убедитесь, что конфигурация сервера в IDE соответствует реальным путям
- для Docker сопоставьте пути контейнера с локальными путями
Влияние на производительность:
- используйте
startwithrequest=trigger вместо yes - отключайте Xdebug, когда он не нужен
- никогда не используйте на production
Проблемы, специфичные для Docker
Если host.docker.internal не работает:
# docker-compose.yml
services:
php:
extra_hosts:
- "host.docker.internal:host-gateway"
Или используйте IP-адрес вашей host-машины напрямую в xdebug.client_host.
Конфигурация в нескольких режимах
Для development-окружений, которым нужны все функции:
[xdebug]
zend_extension=xdebug
; Enable multiple modes
xdebug.mode=debug,develop,coverage
; Debugging settings
xdebug.start_with_request=trigger
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.idekey=PHPSTORM
; Profiling (enable mode when needed)
; xdebug.mode=profile
xdebug.output_dir=/tmp/xdebug
xdebug.profiler_output_name=cachegrind.out.%p
; Logging
xdebug.log=/tmp/xdebug.log
xdebug.log_level=3
Ключевые выводы
- Используйте trigger mode: не включайте отладку для всех запросов
- Профилируйте перед оптимизацией: находите реальные узкие места, а не гадайте
- Настраивайте сопоставление путей: критично для Docker и удалённой отладки
- Никогда не используйте на production: влияние на производительность существенно
- Используйте возможности IDE: точки останова, наблюдения и стеки вызовов
- Проверяйте лог: когда отладка не работает, логи Xdebug подскажут, почему
Xdebug превращает отладку PHP из мучительных print-выражений в профессиональный рабочий процесс разработки. Освойте его — и вы будете решать сложные баги за минуты, а не за часы.