Настраиваем Xdbug в PHPStorm

07.05.2021, 22:28

Одним из самых главных процессов в программировании считается отладка. С помощью отладчика можно посмотреть, что происходит в программе, какие функции выполняются, что хранится в переменных, а также выполнить всё пошагово и точно понять, на какой строчке и при каких значениях переменных случается ошибка.

Например, для PHP используется отладчик Xdebug, PHPStorm - это одна из самых популярных сред разработки. Дальше рассмотрим, как настроить Xdebug в PhpStorm для отладки на локальном компьютере и в Docker.

Настраиваем XDEBUG в PHPSTORM

Поговорим о том, как осуществляется отладка на локальном сервере. 

Весь процесс рассмотрим на примере Ubuntu и интерпретатора PHP, настроенного вместе с Apache. Для других конфигураций пути к файлам могут отличаться, но суть от этого не меняется. Отладчик Xdebug позволяет приостанавливать выполнение кода, смотреть стек вызовов и содержимое переменных. Единственный его минус - нет удобного интерфейса управления. С целью управления отладкой обычнобычно используют IDE. Но IDE не может никак сообщить отладчику что надо запустить отладку, потому что она отвечает только за код. Для этого понадобится ещё расширение для браузера Debug Helper, с помощью которого вы сможете включить режим отладки.

Сначала необходимо установить Xdebug. Для этого выполните:

$ sudo apt install xdebug

Как только процесс установки Xdebug завершился, следует настроить программу так, чтобы при запуске сеанса отладки она пыталась подключится к нашей IDE для управления отладкой. Для этого добавьте такие строчки в файл /etc/php/7.4/apache2/conf.d/20-xdebug.ini в версии Xdebug 2:

$ sudo vi /etc/php/7.4/apache2/conf.d/20-xdebug.ini

zend_extension=xdebug.so
xdebug.remote_enable=1
xdebug.remote_host=127.0.0.1
xdebug.remote_connect_back=1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_autostart=false

Для новой версии лучше всего использовать другой формат:

xdebug.mode=debug
xdebug.start_with_request=trigger
xdebug.discover_client_host = false
xdebug.client_host = 127.0.0.1
xdebug.client_port = 9000

Рассмотрим настройки подробнее. Первый параметр xdebug.mode - режим отладки, возможные варианты:

  • develop - включает вывод дополнительной информации, переопределяет var_dump;
  • debug - режим построчного выполнения кода, именно он нужен в данном случае;
  • profile - профилирование;
  • trace - трассировка выполнения программы.

Несколько режимов включает одновременно при перечислении через запятую. Вторая строчка xdebug.start_with_request определяет как будет запускаться отладчик для режимов debug, trace и им подобных:

  • yes - всегда, при запуске php скриптов;
  • no - запуск только из кода с помощью специальных функций;
  • trigger - по запросу, с помощью специальной переменной в $_ENV, $_POST, $COOKIE или в другом массиве. Этот вариант подходит лучше всего в данном случае чтобы отладчик не запускался когда в этом нет необходимости.

Третья xdebug.discover_client_host имеет значение true, в таком случае xdebug пытается подключится к хосту, переданному в заголовке HTTP_X_FORWARDED_FOR. Поскольку хост указывается в следующей строке, в данном случае эта возможность не нужна. Дальше указывается хост клиента, куда надо подключится для управления отладкой 127.0.0.1 и порт 9000. Именно этот порт используется в PhpStorm по умолчанию на данный момент. После сохранения настроек необходимо выполнить перезагрузку Apache при помощи специальной команды:

$ sudo systemctl restart apache2

Дальше следует настроить PhpStorm. Запустите программу, затем откройте меню Run -> Edit Configurations. Перед вами откроется окно, в котором надо настроить отладчик.

Настраиваем XDEBUG в PHPSTORM

Жмем кнопку + и в открывшемся списке выбираем PHP Remote Debugger:

НАСТРОЙКА XDEBUG В PHPSTORM

В настройках ничего не меняем, указзываем только имя этого способа отладки. Если сервер, с которого будут ожидаться подключения не задать, то будут приниматься все подключения.

Настраиваем XDEBUG в PHPSTORM

Если требуется изменить порт, к которому будет подключаться Xdebug открываем меню File -> Settings -> PHP -> Debug -> DBGp Proxy. Здесь можно указать нужный порт.

Настраиваем XDEBUG в PHPSTORM

Можно говорить, что теперь IDE готова. Теперь кликаем по жуку на верхней панели инструментов. Программа начнет ожидать подключения отладчика и поставим несколько точек останова в коде, просто кликнув перед строчкой с кодом:

Настраиваем XDEBUG в PHPSTORM

Теперь остается выполнить настройку браузера. Для Chrome можно скачать специальное расширение. Установите его и откройте страницу, которую надо отлаживать. Кликните по значку расширения и выберите Debug. Значок расширения станет зеленым:

Настраиваем XDEBUG в PHPSTORM

Обновляем страницу и возвращаемся к PHPStorm. Если всё было сделано верно, там запустится сеанс отладки. При первом запуске программа может попросить настроить соответствия локальных путей к файлам с удаленными. Для локального сервера здесь ничего настраивать не надо. просто жмем Accept:

Настраиваем XDEBUG в PHPSTORM

После этого отладчик остановит выполнение на выбранной точке останова и в программе появится интерфейс отладки:

Настраиваем XDEBUG в PHPSTORM

Теперь разберемся как настроить Xdebug PhpStorm и Docker.

Отладка PHP в DOCKER

C Docker может возникнуть определенная сложность. Поскольку отладчик должен сам подключится к IDE, необходимо пробросить хост в контейнер. В операционной системе Windows это можно сделать с помощью адреса host.docker.internal. Но в Linux, по умолчанию это не происходит. Для того чтобы добавить такой адрес надо добавить в docker-compose такие строчки:

extra_hosts:

host.docker.internal: host-gateway

Используем следующую структуру директории:

Настраиваем XDEBUG в PHPSTORM

Минимально необходимый docker-compose.yaml будет выглядеть вот так:

version: '3.5'
networks:
  losst-network:
services:
  nginx:
    image: nginx
    ports:
        - '8094:80'
    volumes:
        - ./www/:/var/www/
        - ./conf/nginx:/etc/nginx/conf.d
    networks:
        - losst-network
  php-fpm:
    build: 
      context: ./conf/php-fpm
    extra_hosts:
      host.docker.internal: host-gateway
    volumes:
      - ./www:/var/www/
    networks:
      - losst-network

Мы просто объявлем два контейнера, nginx и php-fpm. В первый не вносим зменения, поэтому можно просто брать официальный образ, монтировать папку с исходниками, конфигурационный файл и пробрасывать порт. Во второй контейнер надо установить и настроить Xdebug поэтому его придется собрать на основе официального контейнера php. Для этого же контейнера надо указать директиву extra_hosts, без неё ничего работать не будет. Конфигурация Nginx тоже вполне стандартная:

server {
  listen 80;
  server_name _ !default;
  root /var/www/;
  add_header X-Frame-Options "SAMEORIGIN";
  add_header X-XSS-Protection "1; mode=block";
  add_header X-Content-Type-Options "nosniff";
  index index.html index.htm index.php;
  charset utf-8;
  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }
  error_page 404 /index.php;
  location ~ .php$ {
    fastcgi_pass php-fpm:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    include fastcgi_params;
  }
}

Так настраивается обработка PHP скриптов в контейнере php-fpm, и редирект несуществующих URL на index.php, что вполне стандартно для многих фреймворков и CMS. В Dockerfile контейнера php-fpm, он выглядит вот так:

Устанавливаем xdebug с помощью pecl, а затем копируем его конфигурационный файл в контейнер. Файл:

xdebug.mode=debug
xdebug.start_with_request=trigger
xdebug.discover_client_host = false
xdebug.client_host = host.docker.internal
xdebug.client_port = 9000

В контейнере установлен Xdebug 3 для PHP 8, потому что старая версия с этой версией языка уже не работает, поэтому используется новый синтаксис конфигурации. Ну и хост, host.docker.internal, который раньше был прописан в docker-compose.yaml. Настройка xdebug PHPStorm docker завершена. Дальше вы можете запустить проект:

docker-compose up --build

Теперь, как и в предыдущем варианте вы можете включить в браузере режим отладки, обновить страницу и отладчик успешно подключится к IDE, не смотря на то, что он работает в Docker

Настраиваем XDEBUG в PHPSTORM