Одним из самых главных процессов в программировании считается отладка. С помощью отладчика можно посмотреть, что происходит в программе, какие функции выполняются, что хранится в переменных, а также выполнить всё пошагово и точно понять, на какой строчке и при каких значениях переменных случается ошибка.
Поговорим о том, как осуществляется отладка на локальном сервере.
Весь процесс рассмотрим на примере 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 - режим отладки, возможные варианты:
Несколько режимов включает одновременно при перечислении через запятую. Вторая строчка xdebug.start_with_request определяет как будет запускаться отладчик для режимов debug, trace и им подобных:
Третья 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. Перед вами откроется окно, в котором надо настроить отладчик.
Жмем кнопку + и в открывшемся списке выбираем PHP Remote Debugger:
В настройках ничего не меняем, указываем только имя этого способа отладки. Если сервер, с которого будут ожидаться подключения не задать, то будут приниматься все подключения.
Если требуется изменить порт, к которому будет подключаться Xdebug открываем меню File -> Settings -> PHP -> Debug -> DBGp Proxy. Здесь можно указать нужный порт.
Можно говорить, что теперь IDE готова. Теперь кликаем по жуку на верхней панели инструментов. Программа начнет ожидать подключения отладчика и поставим несколько точек останова в коде, просто кликнув перед строчкой с кодом:
Теперь остается выполнить настройку браузера. Для Chrome можно скачать специальное расширение. Установите его и откройте страницу, которую надо отлаживать. Кликните по значку расширения и выберите Debug. Значок расширения станет зеленым:
Обновляем страницу и возвращаемся к PHPStorm. Если всё было сделано верно, там запустится сеанс отладки. При первом запуске программа может попросить настроить соответствия локальных путей к файлам с удаленными. Для локального сервера здесь ничего настраивать не надо. просто жмем Accept:
После этого отладчик остановит выполнение на выбранной точке останова и в программе появится интерфейс отладки:
Теперь разберемся как настроить Xdebug PhpStorm и Docker.
C Docker может возникнуть определенная сложность. Поскольку отладчик должен сам подключится к IDE, необходимо пробросить хост в контейнер. В операционной системе Windows это можно сделать с помощью адреса host.docker.internal. Но в Linux, по умолчанию это не происходит. Для того чтобы добавить такой адрес надо добавить в docker-compose такие строчки:
extra_hosts:
host.docker.internal: host-gateway
Используем следующую структуру директории:
Минимально необходимый 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