Настройка среды php-разработки с нуля на NetBeans + php + docker + xdebug3

Привет. Это здоровенный мануал-шпаргалка по настройке этой IDE для php-разработки. Здесь будет много текста и картинок.

Полагаю, он больше сгодится для российских и белоруских разработчиков, переходящих c PhpStorm, ибо есть повод. В этом контексте было решено построить себе запасной инструментарий. А ещё я всё-таки закрыл гештальт и познакомился с Netbeans, как давно хотел.

На деле эта IDE во многих отношениях проще шторма, но местами и переусложнена. Будь готов многого лишиться. Постараюсь раскрыть здесь это поподробнее. Поэтому статья иногда будет дополняться и корректироваться.

Версия Netbeans на сию секунду — 24.

В этой статье я установлю NB, настрою его, разверну тестовый проект с php8.3 и xdebug3 на контейнерах и настрою отладку php-скриптов в разных позах.

Я обкатал стек на двух ПК, так что сетап проверен.


Я сразу начну с того, что обычно принято описывать в конце.

Минусы

Поскольку мы потенциально переходим с PhpStorm, то, в сравнении с ним, функционал Netbeans для работы в экосистеме php может расстроить:

  • почти нет плагинов;
  • отвратительное окно настроек;
  • через гуйню не настраивается межстрочный интервал в редакторе, но есть такой вариант — я проверил, работает (о нём ниже чуть подробнее);
  • дубовое управление Dоcker-окружением проекта (есть только список контейнеров и образов, но нельзя переразвернуть композ по кнопке);
  • IDE в принципе не готова для работы с докером, все примочки (composer, phpunit, phpcs…) должны быть локально на хосте;
  • визуальная перегруженность кнопками и дурацкими иконками (поверь, шторм до 2022.* ещё булочка) — и если кнопки и тулбары вроде можно перестроить, то иконки просто будут царапать глаза аки металлическая стружка;
  • докблок считается простым комментом, подсветка элементов внутри очень скудна;
  • нет Shift+Shift и Ctrl+Shift+A, хотя частично это перекрывает Ctrl+I;
  • придётся перевыкать к Ctrl+Shift+F / Ctrl+Shift+R
  • namespace, объявленный в начале файла, должен быть в одном регистре с именами директорий (например, файл лежит в app\MySpace\..., но пространство объявлено как App\MySpace\... — и здесь App будет подсвечен на уровне предупреждения), при этом автодополнение работает исправно;
  • при генерации докблока к функциям/методам не подставляются теги @throws с исключениями, которые могут выбрасываться изнутри с учётом вложенных до усрачки вглубь вызовов других методов;
  • настройки пустых строк в код-стайле довольно скудные и как будто даже глюкавые (например, нельзя убрать пустую строку после сигнатуры класса) — phpcs может подстраховать;
  • не подсвечиваются несовпадения и/или отсутствие возвращаемых типов в сигнатуре, теле и докблоках функций/методов (к вопросу об инспекциях);
  • нет генерации стабов, докблоков, гетерров, сеттеров, тестов… (Alt+Insert в PS);
  • глюкавый Ctrl+Q, Ctrl+F8 и ЛКМ в любых UI-деревьях;
  • встроенная гит-гуйня размазана и неудобна (в шторме она ебейшая);
  • UPD 27.12.22: очень мало инспекций (Hints) и т.н. рефакторингов, однако можно нацепить плагинов (о них далее) и кастомный LSP (пока не пробовал), чем потенциально расширить эти возможности;
  • UPD 27.12.22: рендеринг шрифтов: после шторма очень больно царапает иссене-красное субпиксельное сглаживание;
  • UPD 27.12.22: релизный цикл намного реже, отсюда задержки с фичами языка;
  • ну и ещё туча мелочей, в коих силён шторм и слаб нетбинс (это я так, лишь галопом пробежался) — частично я ещё что-то затрону дальше по тексту.

Но есть и

Плюсы

Может быть их немного, но они дают немного другой, чуть более приятный опыт и сглаживают некоторые углы при миграции:

  1. очень много общих черт и настроек, которые похожим образом разбиты на группы;
  2. визуальная тема FlatLaf Dark для IDE и редактора сильно похожа на дефолтную в шторме;
  3. любые вкладки можно таскать и располагать как угодно внутри главного окна и вытащить за его пределы — это просто сказка;
  4. скорость загрузки, индексирования и в целом работы значительно выше;
  5. UPD 27.12.22: поддержка лигатур шрифтов;
  6. UPD 27.12.22: поддержка inline docblock-ов для переменных внутри скоупа (подсказки работают сносно, но не достаточно — помним про кастомные LSP);
  7. индикатор потребления ОЗУ на виду сразу и работает аналогично (в PS его надо включать отдельно в статусбаре). По этому графику видно, что gc время от времени отрабатывает самостоятельно.

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


Netbeans

Установка

Качаем и ставим последнюю стабильную версию IDE под свою ОС.

UPD 16.01.24: На текущую секунду актуальна 24-я версия, максимальная поддерживаемая версия php — 8.3. Скриншоты будут из разных версий NB, но это ничего не меняет — гуйня между версиями почти не меняется.

Моя ОС — Kubuntu 24.04 и я не брезгую snap-ами, поэтому просто беру и

sudo snap install netbeans --classic

Настройка

Тема

И буквально сразу первое, жизненно важное, что кровь из носа глаз необходимо сделать:

  1. идём в меню:
    Tools / Options / Appearance / Look and Feel
  2. меняем FlatLaf Light на FlatLaf Dark, сохраняемся и перезагружаемся

Теперь, когда глаза не вытекают, можно заниматься настройкой дальше.

Снова идём в меню: Tools / Options.

В окне настроек переходим на вкладку PHP и ждём, пока среда подгрузится. Через пару секунд окно настроек обновится — добавится несколько вкладок.

Выбираем шрифт: на вкладке Fonts & Colors при Language = All languages и Category = Default меняем Font на свой любимый, для меня это JetBrains Mono размера 13.

    Вот так у нас оказывается среда, похожая на шторм. Это снизит нагрузку когнитивную и визуальную.

    PHP-тулинг

    Теперь нужны некоторые настройки, касающиеся php, отладки и всяких примочек по рабочему процессу:

    1. идём в меню:
      Tools / Options / PHP / Debugging
    2. (меняем и) запоминаем Session ID — это нам пригодится, остальное по желанию;
    3. Port по дефолту = 9003, меняют его редко, но всё же можно подогнать при необходимости;
    4. в разделах Code Analisys и Frameworks & Tools отсматриваем (и настраиваем) параметры тех инструментов, которые ты используешь. Они должны быть установлены глобально.

    Редактор кода

    Далее переходим к настройке редактора и код-стайла:

    1. идём в меню: Tools / Options / Editor
    2. включаем Save files when focus is lost в разделе Autosave

    Это поведение идентично дефолтному в шторме, ибо там нет необходимости явно сохранять файл.

    В разделе Folding я предпочту следующие настройки:

    Через это мы быстрее сможем навигироваться по методам классов. Там нередко бывает очень много кода и докблоков, скроллить всю простыню неприятно.

    Переходим в Formatting. Ниже на скриншотах те параметры, которые я изменил чтобы хоть как-то соблюдать привычный PSR-12-based код-стайл.

    А также я выключил:

    • Category = Spaces: Other — After semicolon

    Межстрочный интервал

    По дефолту в редакторе строки слишком близко друг к другу, читать неудобно. Через гуйню, как я уже писал, даже в 17-ой версии интервал почему-то не настраивается (либо я не нашёл, ткните носом). Поэтому идём в конфиг:

    # если на нашёлся этот:
    ~/.netbeans/<VERSION>/config/Editors/Preferences/org-netbeans-modules-editor-settings-CustomPreferences.xml
    # значит этот:
    ~/snap/netbeans/current/config/Editors/Preferences/org-netbeans-modules-editor-settings-CustomPreferences.xml

    и перед закрывающим тегом </editor-preferences> вставить строку:

    <entry javaType="java.lang.Float" name="line-height-correction" xml:space="preserve"><value><![CDATA[1.4]]></value></entry>

    где 1.4 — собственно, коэффициент интервала. Больше — дальше.

    С редактором мы закончили. Теперь код будет красив и читабелен.

    Горячие клавиши

    Горячие клавиши настраиваются в Tools / Options / Keymap. Тут всё просто, выбираем Profile = Idea и точечно подгоняем под привычки.

    Терминал

    В качестве оболочки терминала я использую zsh с oh-my-zsh и темой powerline10k. Вот как это выглядит по дефолту:

    До

    Это потому, что шрифт для красивостей в настройках omz указан MesloLGS NF. Его же я выбираю в Tools / Options / Miscellaneous / Terminal / Font:

    Здесь же можно выставить Tab Size = 4, чтобы больше выхлопа помещалось на экран
    После

    Плагины

    Открывай окно настройки плагинов: Tools / Plugins

    На вкладке Available Plugins включай те необходимые, которые начинаются. Минимум для меня это:

    1. PHP CS Fixer
    2. PHP Enhancements
    3. Sort Line Tools
    4. NetBeans Markdown

    Есть ещё несколько примечательных, но совершенно необязательных:

    1. No Newline Resolver
    2. gitignore.io
    3. REST Client
    4. Scratch Files

    Отмечай чекбоксами, жми Install и подтверждай лицензии. NB может спросить доверять ли самоподсписанным сертификатам, которыми подписаны некоторые плагины — соглашайся.

    Также на вкладке Installed включай крыжик Show details и выключай всё некритическое (см. колонку Category), что тебе не нужно — так ты сможешь сэкономить некоторое время на запуске IDE.

      • все плагины с упоминанием слов:
        • Hudson
        • Spellchecker
        • Gradle
        • AngularJS
        • React
        • NodeJS
        • TSX
        • JSX
        • JavaFX
      • категории целиком:
        • Developing NetBeans
        • Gradle
        • Java, JavaFX 2, Java SE, Java Web and EE
        • JavaScript
        • Kotlin
        • Cloud
        • C/C++
      • и конкретные плагины:
        • Subversion, Mercurial
        • Bugzilla
        • Local Tasks
        • FlexMark Library
        • Ant
        • TypeScript

      Вероятно, некоторые плагины снова окажутся включенными после перезагрузки IDE — да и болт с ними. Указанное выше и всё остальное — на твоё усмотрение по необходимостям. Как минимум, я показал что где.

      Пфуф, в IDE вроде бы пока всё.


      Docker

      NB всё ещё не поддерживает отладку через докер. Эта настройка влияет только на комфорт управления контейнерами изнутри NB.

      Легко устанавливается по официальным мануалам. Для Ubuntu у меня уже есть готовый скрипт, можно использовать его.

      После установки мы можем вернуться в NB и открыть Window / Services. В открывшемся списке следует найти Docker, клацнуть ПКМ и выбрать Add Docker.

      В следующем окне достаточно нажать Finish, но перед этим можно и Test Connection, чтобы убедиться, что всё с ним окей.

      Когда в системе уже есть какие-то (не)запущенные контейнеры, они отобразятся в этом дереве. Для каждого контейнера там доступны базовые фичи вроде инспекта, логов, перезапуска и вот этого всего. Типикал.


      php8.3 + xdebug

      Пример проекта в рамках этой статьи будет построен так:

      Здесь открыты основные конфиги. Скриншот старый, но суть та же.

      У нас есть два контейнера — с nginx и с php + xdebug. Nginx в первом контейнере ловит HTTP-запросы и отдаёт во второй, где пыха их обрабатывает, а xdebug встревает когда надо. Суть тут элементарна: нам всего лишь надо проверить связь xdebug изнутри контейнера с IDE, проект нужен только для наглядности.

      Можешь выкачать мой репозиторий и открыть его как новый проект в NB. Запусти контейнеры командой:

      $ docker compose up -d --build

      Netbeans + xdebug

      В настройках проекта File / Project Properties:

      На этом скриншоте порт 9090 вместо 8888 — не обращай внимания, это я делал для локальной проверки
      1. перейдём в раздел Run configuration
      2. очистим Index File
      3. нажмём Advanced
      4. ткнём на Do Not Open Web Browser (чтобы браузер не подпрыгивал при каждом старте отладки)
      5. cопоставим путь к исходникам проекта с директорией на сервере
      6. ОК
      7. ОК

      Теперь можно нажимать кнопку Debug Project на тулбаре:

      Он изменит свой вид:

      NB будет слушать порт 9003 и ожидать подключения.

      Поставь точку останова в файле index.php на любой строке нажатием на её номер.

      Проверка GET-запросом

      Отправь запрос:

      $ curl http://localhost:8888/index.php \
          -d 'XDEBUG_SESSION_START=netbeans-xdebug'

      Ну или можешь открыть http://localhost:8888/index.php в браузере.

      Если ты сразу получил ответ, но брейкпоинт не отработал, то можешь поставить расширение Xdebug Helper в свой браузер (Chromium, Firefox) и с его помощью установить cookie со значением netbeans-xdebug. Тогда пыха точно поймает её и xdebug возбудится.

      Если браузер или curl подвис, значит бряк сработал, IDE тормознула выполнение и ждёт твоих действий. На скриншоте выше показано именно это состояние. Обрати внимание в окно Variables и зелёную строчку в index.php.

      Также обрати внимание на port и idekey в конфиге xdebug.ini — мы их видели выше при настройке NB. Они должны совпадать.

      Хорошо, мы сумели поймать бряк на веб-приложении через браузер. Это один из сценариев разработки, а как насчёт API? Выше мы поймали простой GET-запрос, давай отправим POST.


      Проверка POST-запросом

      Для этого выполню команду:

      $ curl -X POST http://localhost:8888/index.php \
          -d 'XDEBUG_SESSION_START=netbeans-xdebug'

      Немного про XDEBUG_SESSION_START. Это параметр xdebug, который, возбуждает отладчик согласно его дефолтных настроек. Без него отладка сейчас не запустится.

      Запускаем команду, теперь подвис и терминал: строка с точкой останова снова позеленела, а в Variables мы видим содержимое переменных:


      Проверка с триггером

      Xdebug умеет триггериться по какому-то конкретному признаку, вместо того, чтобы тупо стартовать всегда. Это имеет смысл только с HTTP-запросами. Поэтому немного модифицируем наш предыдущий пример.

      В xdebug.ini добавим две строки:

      xdebug.start_with_request=trigger
      xdebug.trigger=go

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

      $ docker compose down
      $ docker compose up -d --build

      Теперь исправим нашу прошлую команду curl, добавив куку:

      $ curl -X POST http://localhost:8888/index.php \
          -H 'Cookie: XDEBUG_TRIGGER=go'

      …да как с добрым утром:

      Отлично. Теперь, например, нам нужно запускать тесты или отладить команду artisan, а эти вещи запускаются из терминала, там запрос не отправишь. Давай покроем этот случай.


      Проверка CLI-скриптов

      Здесь, разумеется, мы тоже для начала воспользуемся терминалом. В этот раз мы выполним такую команду:

      docker exec test-php php \
          -dxdebug.mode=debug \
          -dxdebug.start_with_request=1 \
          index.php 

      Что это значит, построчно:

      1. выполняем команду php внутри контейнера test-php;
      2. переопределяем флагом -d параметр xdebug.mode=debug, чтобы отрабатывали бряки;
      3. переопределяем флагом -d параметр xdebug.start_with_request=1, чтобы отладчик подключился при выполнении скрипта;
      4. имя файла скрипта.

      Пункты 2 и 3 нужно прокидывать явно, потому что для cli-окружения у пыхи свой отдельный конфиг, который мы здесь не готовили, а по дефолту перекрытые нами параметры там имеют другие значения.

      Выполняю команду и наблюдаю ту же картину:

      Можно настроить собственную конфигурацию запуска cli-скриптов на уровне IDE. Делается это в настройках проекта:

      Однако здесь всплывает недостаток NB перед PS: наш интерпретатор находится в контейнере, а здесь мы можем настроить выполнение скрипта только на хосте. PS же умеет ловить отладчик при запуске cli-скриптов прямо изнутри контейнеров.

      UPD 07.04.2023: для решения этой проблемы в NB я написал специальный хелпер, которым следует подменить интерпретатор в настройках NB. Подробности читай в этой статье.

      Это, как и всё остальное, оставлю на твою фантазию и потребности.

      Заключение

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

      Эту статью я могу скорректировать и дополнять, так что, надеюсь, она действительно будет полезной.

      Первые личные впечатления. Как-то всё кисло-сладко, что-ли… Не могу сказать, что сейчас я готов юзать NB на постоянке, но это очень годная среда под пыху, с ней точно стоит поработать. Как будто от шторма отрезали знатный кусок полезностей и всунули фичи для java. Сильной боли я пока не почувствовал, но джава торчит из-за каждого угла. Надо будет ради пробы посидеть денёк-другой и погрузиться в рабочий процесс — точно повылезает всякое, а о самом важном допишу.

      Жду фидбек. Если ты что-то знаешь по сабжу — поделись со мной, я пощупаю и тоже добавлю инфу в пост.

      Полезные материалы

      https://git.axenov.dev/anthony/nb-test

      https://xdebug.org/docs/all_settings

      https://netbeans.apache.org/tutorial/main/kb/docs/php/

      https://artofcoding.in/configure-xdebug-in-docker-to-use-with-netbeans/

      https://dev.to/miqwit/using-php-xdebug-in-a-docker-with-netbeans-3hc9

      http://fkn.ktu10.com/?q=node/11494

      https://stackoverflow.com/questions/65107145/docker-php-with-xdebug-3-env-xdebug-mode-doesnt-work

      https://php.tutorials24x7.com/blog/how-to-debug-php-in-netbeans-on-windows

      https://blog.programster.org/?search_term=netbeans

      P.S.

      27-28.12.2022:

      • добавлен блок про плагины;
      • удалён блок про настройку Code Completion;
      • скорректированы минусы, плюсы, актуальная версия Netbeans;
      • в Полезные материалы добавлена ссылка на blog.programster.org и netbeans.apache.org/kb
      • уточнение про лигатуры;
      • мелкофиксы по редактуре и форматированию текста.

      02.03.2023:

      • версия NB 17;
      • убрал упоминание docker-compose;
      • добавил список плагинов, которые я выключаю у себя;
      • мелкофиксы по редактуре и форматированию текста.

      16.03.2023: добавил отдельный раздел про межстрочный интервал.

      07.04.2023:

      • добавил красивостей, местами поправил форматирование;
      • добавил оглавление;
      • в главе про отладку CLI добавил ссылку на мою статью о хелпере.

      08.07.2024:

      • актуализировал статью в целом под версию NB 24 (некоторые скриншоты, уточнения), проверил работоспособность (часть скриншотов оставил с прошлых версий NB);
      • общие мелкие корректировки по тексту и форматированию.
      1. Не смотря на российские корни JB и их т. н. «предательство», я уважаю их и считаю их IDE отличными. Местами глюкавыми, медленными и прожорливыми. Я поддерживаю далеко не все их решения по фичам, не понимаю смысл и ориентированность некоторых продуктов (Fleet, Aqua, Spaces). Но среды разработки — моё почтение, господа, это стандарт де-факто. То, что создаётся и продаётся на платформе idea, по-настоящему стоит внимания и точно окупает любые деньги. Эта репутация и популярность заслужена не на пуcтом месте. Как только у меня появится возможность платить за шторм — я буду платить.

        Призывать к пиратству не буду, но оно всегда остаётся как опция и такой выбор можно понять, потому что не все готовы связываться со всяким геморроем по оплате через зарубеж. Моя позиция относительно пиратского ПО строго негативная, потому что я в своё время от этого устал. Они постоянно улучшают защиту, которую тебе постоянно приходится обходить, чтобы их налюбить. Конструктива тут маловато.
      2. Персональная ежемесячная подписка на PhpStorm 2022.*, любезно продлённая бесплатно JetBrains до осени 2022 года, уже давно закончилась, так что я сразу перелез на корпоративную (которая, подозреваю, скоро тоже превратится в тыкву). Но ещё перед окончанием личной, я раздумывал и неспеша прощупывал почву для перехода.
        Этот пост — результат моих изысканий. Сегодня из сред разработки для php после шторма есть только Netbeans. Остальное — текстовые редакторы, которые ни по каким параметрам не могут сравниваться ни в одной позе, альтернативами не являются и упоминания в рамках поста не достойны.
      3. Если подписка на шторм оплачивалась более года, то в личном кабинете становится доступна полноценная лицензия на прошлогоднюю версию. Какое-то время можно использовать и её, но никаких обновлений, понятное дело, не будет. Эта версия уже протухла и будет только мешать.
      4. Мои критерии, которым удовлетворяют и PS, и NB:
        • если ПО покрывает всё, что мне нужно, и даже больше — (бес)платность как таковая не имеет значения, на первое место встаёт вопрос о количестве и размере требуемых платежей;
        • FOSS предпочтителен, но необязателен: разработка открытых продуктов мало чем отличается от проприетарных в части организации работы, а успех популярного FOSS = возраст + постоянная поддержка сообществом + открытость к сообществу + регулярность релизного цикла;
        • ПО должно развиваться и обновляться хотя бы пару раз в год, иначе это моча;
        • обращать внимание на язык программирования, на котором написана тулза — тупое уебанство и не имеет никакого значения ни на что, как и имя/название/география/сексуальная ориентация разработчика;
        • а вот политические взгляды разработчика FOSS — тут надо быть хирургически аккуратным. В 2022 году повылезало как-то многовато долбоёбов, которые начали вмешивать какое-то своё личное говно в опенсорс: от мусора в терминале, документации и OSI-лицензиях до вывода из строя сторонних продуктов и инфраструктур, использующих их проект. Мейнтейнеры почему-то вдруг решили, что они ахуеть как вправе форсить людям свои проблемы и создавать новые, помпезно выказывая свою политическую позицию.

          К сожалению, у этого есть даже термин — protestware. Здесь с чем-то придётся мириться, а чему-то мучительно искать меньшее альтернативное зло. Долбоёбы, в конце концов, тоже важные люди, ибо они балансируют добро и зло в этом мире, так что я на них не в обиде.

          Почему этот пункт не касается JB, они же ушли из РФ/РБ? Потому что они обязаны соблюдать местное законодательство; потому что они не форсят политоту; потому что PS не является FOSS (т.е. левые долбоёбы не пушат всякое говно); потому что мою подписку они продлили мне на полгода в ущерб себе; потому что корпоративные лицензии продолжали действовать после окончания личных подписок; и потому что я могу им простить многое просто попытавшись понять их обстоятельства с точки зрения бизнеса.

      2 комментария

        1. Для диагностики работы докера могут помочь команды:

          docker ps
          docker info
          sudo systemctl status docker.service
          sudo systemctl status containerd.service
          sudo journalctl -u dockerd

          Ещё доп. сведения: https://www.howtogeek.com/devops/how-to-check-if-the-docker-daemon-or-a-container-is-running/

          Исходя из результатов этих команд можно дальше гуглить решение.
          Ещё надо отметить, что текущий пользователь обязан состоять в группе docker. Если не — нужно добавить и перелогиниться в учётку.
          Всё это касается linux-окружений, про винду ничего не могу сказать.

      Добавить комментарий

      Ваш адрес email не будет опубликован. Обязательные поля помечены *