Использование PhpStorm, Docker и Xdebug 3 на PHP 8.1

Использование PhpStorm, Docker и Xdebug 3 на PHP 8.1

27 апреля 2022 г.

Руководство по отладке всего в PhpStorm (IDE, браузер [fpm], cli и воркеры)


В этом руководстве мы настроим нашу локальную докеризированную среду разработки PHP для использования PhpStorm и Xdebug. Мы также обеспечим возможность запуска тестов PHPUnit из командной строки, а также из PhpStorm. Существует также видео на Youtube, которое проведет вас через весь процесс.


https://www.youtube.com/watch?v=bZ1MiynqT98


Все примеры кода общедоступны в моем [репозитории Docker PHP Tutorial на github] (https://github.com/paslandau/docker-php-tutorial). Вы найдете ветку для этого руководства по адресу part-4-2-phpstorm-docker-xdebug-3-php-8-1-in-2022. Это руководство ранее было опубликовано в моем личном блоге [PhpStorm, Docker и Xdebug 3 на PHP 8.1 в 2022 году] (https://www.pascallandau.com/blog/phpstorm-docker-xdebug-3-php-8-1- в-2022/).


Вступление


Эта статья представляет собой обновление [Настройка PhpStorm с Xdebug для локальной разработки в Docker] (https://www.pascallandau.com/blog/setup-phpstorm-with-xdebug-on-docker/), но также будет охватывать " остальные случаи" отладки php-fpm и рабочих процессов php.


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


Это снижает сложность и удаляет все надоедливые предупреждения о том, что «ключи SSH выставлены в репозитории».


Установить инструменты


Установить композитор


Composer устанавливается путем извлечения официального образа докера композитора и простого «копирования» исполняемого файла композитора в базовое изображение php. Кроме того, композитору нужны расширения mbstring и phar.


Файл: .docker/images/php/base/Dockerfile


ARG ALPINE_VERSION


АРГУМЕНТ КОМПОЗИТОР_ВЕРСИЯ


ОТ композитора: ${COMPOSER_VERSION} в качестве композитора


ОТ alpine: ${ALPINE_VERSION} в качестве базы


ЗАПУСТИТЬ apk добавить --update --no-cache \


php-mbstring~=${TARGET_PHP_VERSION} \


php-phar~=${TARGET_PHP_VERSION} \


КОПИРОВАТЬ --from=composer /usr/bin/composer /usr/local/bin/composer


Поскольку мы хотим, чтобы наша сборка была детерминированной, мы «закрепляем» версию композитора, добавляя переменную COMPOSER_VERSION в файл .docker/.env


COMPOSER_VERSION=2.2.5


и используя его в .docker/docker-compose/docker-compose-php-base.yml:


Сервисы:


PHP-база:


строить:


аргументы:


  • COMPOSER_VERSION=${COMPOSER_VERSION?}

Установить Xdebug


Установите расширение через apk (только для локальной цели):


Файл: .docker/images/php/base/Dockerfile


ИЗ базы как местный


ЗАПУСТИТЬ apk добавить --no-cache --update \


php-xdebug~=${TARGET_PHP_VERSION} \


убедитесь, что xdebug не включен по умолчанию


&& rm -f /etc/php8/conf.d/00_xdebug.ini


Мы также не хотим включать xdebug сразу, а только тогда, когда нам это нужно (из-за снижения производительности при включении расширения), поэтому мы удаляем файл конфигурации по умолчанию и отключаем расширение в приложении .ini файл


Файл: .docker/images/php/base/conf.d/zz-app-local.ini


; Примечание:


; Удалить комментарий ; включить отладку


;zend_extension=xdebug


xdebug.client_host=host.docker.internal


xdebug.start_with_request=да


xdebug.mode=отладка


См. Исправить Xdebug в PhpStorm при запуске из контейнера Docker для объяснения параметра xdebug.client_host=host.docker.internal (ранее называвшегося xdebug.remote_host в xdebug < 3). Это по-прежнему будет работать из коробки для Docker Desktop, но для пользователей Linux нам нужно добавить магическую ссылку host-gateway ко всем контейнерам PHP (мы не можем добавить ее в базовый образ php, потому что это является параметром времени выполнения):


Сервисы:


услуга:


дополнительные_хосты:


  • host.docker.internal: хост-шлюз

Наконец, нам нужно добавить [переменную среды] (https://www.jetbrains.com/help/phpstorm/debugging-a-php-cli-script.html)PHP_IDE_CONFIG ко всем контейнерам PHP. Переменная определяется как PHP_IDE_CONFIG=serverName=dofroscra, где «dofroscra» — это имя сервера, который мы позже настроим для отладки. Поскольку нам нужно одно и то же значение в нескольких местах, переменная настроена в .docker/.env:


PHP_IDE_CONFIG=имя_сервера=дофроскрэ


А затем добавил в .docker/docker-compose/docker-compose.local.yml


``ямл


Сервисы:


php-fpm:


Окружающая среда:


  • PHP_IDE_CONFIG=${PHP_IDE_CONFIG?}

PHP-работник:


Окружающая среда:


  • PHP_IDE_CONFIG=${PHP_IDE_CONFIG?}

заявление:


Окружающая среда:


  • PHP_IDE_CONFIG=${PHP_IDE_CONFIG?}

Установить PHPUnit


PHPUnit будет установлен через composer, но не будет "встроен в образ" для локальной разработки. Таким образом, мы должны запустить composer require в контейнере. Чтобы сделать это более удобным, в .make/01-00-application-setup.mk добавлена ​​цель make для запуска произвольных команд композитора:


.PHONY: композитор


composer: ## Запуск команд композитора. Укажите команду, например. через ARGS="установить"


$(EXECUTE_IN_APPLICATION_CONTAINER) композитор $(ARGS);


Это позволяет мне запускать make composer ARGS="install" из хост-системы для выполнения composer install в контейнере. Как следствие, composer будет использовать версию PHP и расширения контейнера application для установки зависимостей, но я по-прежнему буду видеть установленные файлы локально, потому что кодовая база настроена как том для контейнера.


Перед установкой phpunit мы должны добавить в контейнер необходимые расширения dom и xml


Файл: .docker/images/php/base/Dockerfile


ЗАПУСТИТЬ apk добавить --update --no-cache \


php-dom~=${TARGET_PHP_VERSION} \


php-xml~=${TARGET_PHP_VERSION} \


а также перестроить и перезапустить настройку докера через


``` ударить


сделать докер-сборку


отключить докер


делать докер-ап


Теперь мы можем добавить phpunit через


``` ударить


make composer ARGS='require "phpunit/phpunit"'


который создаст файл composer.json и настроит каталог vendor/:


$ make composer ARGS='require "phpunit/phpunit"'


Использование версии ^9.5 для phpunit/phpunit


./composer.json создан


Запуск обновления композитора phpunit/phpunit


Загрузка репозиториев композитора с информацией о пакете


Обновление зависимостей


я также добавил


  • минимальный конфигурационный файл phpunit.xml

  • тестовый пример в tests/SomeTest.php

  • и новый Makefile для «всего, что связано с qa» в .make/01-02-application-qa.mk:

``ямл


@ [Приложение: QA]


.ФОНИЯ: тест


test: ## Запустить набор тестов


$(EXECUTE_IN_WORKER_CONTAINER) поставщик/бен/phpunit -c phpunit.xml


Так что я могу запускать тесты просто через make test


$ сделать тест


ENV=local TAG=latest DOCKER_REGISTRY=docker.io DOCKER_NAMESPACE=dofroscra APP_USER_NAME=application APP_GROUP_NAME=application docker-compose -p dofroscra_local --env-file ./.docker/.env -f ./.docker/docker-compose/docker -compose.yml -f ./.docker/docker-compose/docker-compose.local.yml exec -T --user application php-worker vendor/bin/phpunit


PHPUnit 9.5.13 Себастьяна Бергманна и соавторов.


. 1 / 1 (100%)


Время: 00:00.324, Память: 4,00 МБ


ОК (1 тест, 1 утверждение)


Установить SSH


Мы будем выполнять команды из PhpStorm через ssh в контейнере application. Как уже упоминалось, мы не будем использовать файл ключа для аутентификации, а вместо этого просто используем пароль, настроенный с помощью переменной APP_SSH_PASSWORD в .docker/.env и переданный образу в .docker/docker-compose. /docker-compose.local.yml. Кроме того, мы сопоставляем порт 2222 хост-системы с портом 22 контейнера приложения и обеспечиваем совместное использование кодовой базы в виде тома между хостом и контейнером.


``ямл


заявление:


строить:


аргументы:


  • APP_SSH_PASSWORD=${APP_SSH_PASSWORD?}

тома:


  • ${APP_CODE_PATH_HOST?}:${APP_CODE_PATH_CONTAINER?}

порты:


  • "${APPLICATION_SSH_HOST_PORT:-2222}:22"

Контейнер уже содержит openssh и устанавливает пароль


АРГ BASE_IMAGE


ОТ ${BASE_IMAGE} в качестве базы


ИЗ базы как местный


ЗАПУСТИТЬ apk добавить --no-cache --update \


опенсш


ARG APP_SSH_PASSWORD


ЗАПУСК echo "$APP_USER_NAME:$APP_SSH_PASSWORD" | пароль 2>&1


Требуется для запуска sshd, иначе контейнер выдаст ошибку при запуске с сообщением


"sshd: нет доступных хост-ключей -- выход."


@см. https://stackoverflow.com/a/65348102/413531


ЗАПУСК ssh-keygen -A


мы используем конфигурацию развертывания SSH в PhpStorm для локальной разработки


ЭКСПОЗИЦИЯ 22


CMD ["/usr/sbin/sshd", "-D"]


Настройка PhpStorm


Мы настроим удаленный интерпретатор PHP, который использует SSH-соединение для запуска команд в контейнере приложения. Раньше мы использовали конфигурацию развертывания SFTP, которая было несколько запутанным («Что здесь делает SFTP?»), поэтому вместо этого мы будем использовать [Конфигурацию SSH] (https://www.jetbrains.com/help/phpstorm/create-ssh-configurations.html) и настроим сопоставления путей в интерфейсе Cli Interpreter


Конфигурация SSH


В `Файл | Настройки | Инструменты | Конфигурации SSH создайте новую конфигурацию SSH с именем «Docker PHP Tutorial» со ​​следующими настройками.


  • Хост: 127.0.0.1

  • Порт: см. «APPLICATION_SSH_HOST_PORT» в «.docker/docker-compose/docker-compose.local.yml».

  • Имя пользователя: см. «APP_USER_NAME» в «.make/.env».

  • Тип аутентификации: Пароль

  • Пароль: см. APP_SSH_PASSWORD в .docker/.env


PHP-интерпретатор


В Файл | Настройки | PHP добавить новый интерпретатор PHP CLI, который использует новую конфигурацию SSH.



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


корень:/var/www/app# php -i | grep extension_dir


extension_dir => /usr/lib/php8/modules => /usr/lib/php8/modules


root:/var/www/app# ll /usr/lib/php8/modules | grep xdebug


-rwxr-xr-x 1 root root 303936 9 января 00:21 xdebug.so


Нам все еще нужно исправить Xdebug в PhpStorm при запуске из контейнера Docker, добавив пользовательскую опцию PHP для xdebug.client_host=host.docker.internal. Это же значение мы используем в .docker/images/php/base/conf.d/zz-app-local.ini.



В обзоре интерпретатора мы теперь должны настроить сопоставления путей, чтобы PhpStorm знал, «какой локальный файл принадлежит какому удаленному». Удаленная папка определяется в .docker/.env через


APP_CODE_PATH_CONTAINER=/var/www/приложение



После этого мы можем установить точку останова, например. в setup.php и начните отладку:



На снимке экрана показано, что PhpStorm добавляет расширение Xdebug, которое мы определили ранее.


PHPUnit


phpunit настраивается через File | Настройки | PHP | Тестовые рамки. Сначала мы выбираем интерпретатор, который мы только что добавили



Затем мы добавляем пути к скрипту автозагрузки композитора и файлу конфигурации phpunit.xml.



Теперь PhpStorm будет выполнять тесты с использованием интерпретатора PHP в контейнере приложения.



Отладка


Прежде всего, если вы еще этого не сделали, ознакомьтесь с [официальной документацией xdebug] (https://xdebug.org/docs/step_debug). Дерик отлично справляется с подробным объяснением xdebug, включая несколько полезных видеороликов, таких как Xdebug 3: Xdebug с Docker и PhpStorm за 5 минут


Код отладки, выполненный через PhpStorm


Это уже должно работать из коробки. Просто установите точку останова, щелкните файл правой кнопкой мыши и выберите «Отладка '...'».



Код отладки, выполняемый через php-fpm, cli или из воркера


Для кода, который выполняется «напрямую» контейнером без PhpStorm, нам сначала нужно включить xdebug в контейнере, удалив ; перед расширением в /etc/php8/conf.d/zz-app -local.ini


; Примечание:


; Удалить комментарий ; включить отладку


zend_extension=xdebug


Чтобы сделать это немного более удобным, мы используем специальные рецепты make для этих действий в .make/01-01-application-commands.mk


.PHONY: выполнение в контейнере


execute-in-container: ## Выполнить команду в контейнере. Например. через «сделать выполнение в контейнере DOCKER_SERVICE_NAME=php-fpm COMMAND="echo 'hello'"


@$(если $(DOCKER_SERVICE_NAME),,$(ошибка DOCKER_SERVICE_NAME не определена))


@$(если $(КОМАНДА),,$(ошибка КОМАНДА не определена))


$(EXECUTE_IN_CONTAINER) $(КОМАНДА);


.PHONY: включить-xdebug


enable-xdebug: ## Включить xdebug в данном контейнере, указанном "DOCKER_SERVICE_NAME". Например. "сделать enable-xdebug DOCKER_SERVICE_NAME=php-fpm"


"$(MAKE)" выполнение в контейнере APP_USER_NAME="root" DOCKER_SERVICE_NAME=$(DOCKER_SERVICE_NAME) COMMAND="sed -i 's/.*zend_extension=xdebug/zend_extension=xdebug/' '/etc/php8/conf. d/zz-app-local.ini'"


.PHONY: отключить-xdebug


disable-xdebug: ## Отключить xdebug в заданном контейнере, указанном "DOCKER_SERVICE_NAME". Например. "сделать enable-xdebug DOCKER_SERVICE_NAME=php-fpm"


"$(MAKE)" выполнение в контейнере APP_USER_NAME="root" DOCKER_SERVICE_NAME=$(DOCKER_SERVICE_NAME) COMMAND="sed -i 's/.*zend_extension=xdebug/;zend_extension=xdebug/' '/etc/php8/conf .d/zz-app-local.ini'"


Чтобы перехватывать входящие запросы, нам нужно заставить PhpStorm прослушивать отладочные соединения PHP через Run | Начать прослушивание отладочных соединений PHP.



Соответствующие порты настраиваются в File | Настройки | PHP | Отладка. В Xdebug < 3 порт по умолчанию был 9000, а в [Xdebug 3] (https://xdebug.org/docs/all_settings#client_port)9003



Наконец, нам нужно добавить сервер через File | Настройки | PHP | Серверы



Имя сервера должно совпадать со значением ключа serverName в переменной среды PHP_IDE_CONFIG, которую мы ранее настроили как serverName=dofroscra.


php-fpm

Для php-fpm мы должны [перезапустить] (https://stackoverflow.com/a/43076457) процесс php-fpm без перезапуска контейнера после того, как мы активировали xdebug через


``` ударить


убить -USR2 1


Так как это трудно запомнить, мы добавляем цель make в .make/01-01-application-commands.mk


@см. https://stackoverflow.com/a/43076457


.PHONY: перезапуск-php-fpm


restart-php-fpm: ## Перезапустите службу php-fpm


"$(MAKE)" выполнение в контейнере DOCKER_SERVICE_NAME=$(DOCKER_SERVICE_NAME_PHP_FPM) COMMAND="kill -USR2 1"


Итак, теперь мы можем просто запустить


``` ударить


сделать enable-xdebug DOCKER_SERVICE_NAME=php-fpm


сделать перезапуск-php-fpm


Установка точки останова в public/index.php и открытие http://127.0.0.1/ в браузере или через curl http://127.0.0.1/ остановит выполнение, как и ожидалось.



кли

Вместо того, чтобы запускать PHP-скрипт через HTTP-запрос, мы также можем запускать сценарии CLI — подумайте, например, о цели make setup-db. Чтобы отладить такие вызовы, нам нужно выполнить те же шаги, что и раньше:


  • включить расширение xdebug в контейнере application

  • "Прослушивание отладочных соединений PHP" от PhpStorm

Выполнение следующих целей make приведет к срабатыванию точки останова в setup.php:


``` ударить


make enable-xdebug DOCKER_SERVICE_NAME = приложение


сделать setup-db


php-воркеры

И, наконец, то же самое для длительных процессов PHP (они же рабочие). Как прежде:


  • включить расширение xdebug в контейнере php-worker

  • "Прослушивание отладочных соединений PHP" от PhpStorm

  • перезапустить рабочие php

Выполнение следующих целей make вызовет точку останова в worker.php:


make enable-xdebug DOCKER_SERVICE_NAME=php-worker


сделать перезапуск рабочих



Подведение итогов


Поздравляем, вы сделали это! Если что-то еще не совсем ясно, не стесняйтесь оставлять комментарии. Кроме того, теперь у вас должна быть полностью настроенная установка для разработки, которая работает с PhpStorm в качестве вашей IDE.


Если вам нравится такой контент, не стесняйтесь:


  • подписывайтесь на меня в [Твиттере] (https://twitter.com/PascalLandau)


  • и обязательно ознакомьтесь с остальными частями [Учебника по Docker PHP на Github] (https://github.com/paslandau/docker-php-tutorial)

Также опубликовано [Здесь] (https://www.pascallandau.com/blog/phpstorm-docker-xdebug-3-php-8-1-in-2022/)! [] (https://cdn.hackernoon.com /images/Syb8pJ61mKPGZO7h4wUZ8zlDwJJ3-2022-04-27T08:15:13.467Z-cl2haxwe300430as6628banyg)



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE