Что такое команды в Symfony? Это код, который можно выполнять через PHP CLI посредством вызова.
php bin/console {команда}
Команды позволяют ускорить разработку и отладку создаваемого кода. Например, нужно разработать синхронизацию товаров с 1С – целесообразно начинать разработку такого функционала с разработки команды, и Symfony Framework предоставляет удобный способ для начала работы. Для этого программисту достаточно выполнить:
php bin/console make:command
После чего фрэймворк попросит ввести название команды, по которой эта команда будет запускаться. Пример:
Очень удобно. Теперь программисту достаточно определить аргументы и опции вызова команды, а также описание самой команды и главный код, который команда будет выполнять.
Пример на скриншоте, после редактирования Sync1cCommand.php
В данном примере определён аргумент (addArgument) – аргумент указывает сразу после вызова команды, а опции обязательно указывать через «два тире» → --force
У каждого аргумента и параметра есть свойства: обязательность заполнения, обязательность значения (для опций), короткое название опции и текстовое описание аргумента или опции.
Кроме того, фреймворк предоставляет вспомогательные библиотеки, которые позволяют задавать (вести диалог) с помощью команд:
- ( https://symfony.com/doc/current/components/console/helpers/questionhelper.html ) , подсвечивать выводимый текст и всячески его форматировать
- ( https://symfony.com/doc/current/console/style.html , https://symfony.com/doc/current/components/console/helpers/progressbar.html )
- а также следить за кол-вом одновременно запущенных одинаковых команд ( https://symfony.com/doc/current/console/lockable_trait.html )
Кроме того, каждая внешняя библиотека или подсистема фреймворка добавляет свой набор команд, с помощью которого отладка и разработка ускоряется в разы.
Когда лучше всего применять команды?
- Если необходимо выполнять по расписанию какую-либо операцию, например: почтовая рассылка, синхронизация данных, уведомления, очистка логов и т. д.
- Если необходимо разово исправить ошибки в базе данных и скорректировать БД, но при этом операция требует не только SQL-кода, но и ещё обращения во внешние сервисы, или выполнения определённой логики, которую не повторить через SQL-код. В таком случае команда будет предпочтительней миграции.
- Если необходимо создавать администраторские функции, которые должны быть в системе, но не должны быть доступны через интерфейс.
- Если необходимо протестировать работу какого-либо кода, но нельзя вмешиваться в основной (рабочий) код. Команда позволит повторить/с эмулировать необходимые условия.
- Предпродуктовая подготовка: инсталлеры, проверка конфигурации и т. д.
Как переопределять команды?
Стоит учитывать, что Symfony Framework позволяет переопределять/конфигурировать и безопасно вмешиваться в логику своих компонентов с помощью «контейнера зависимостей». Каждая команда – это такой же «сервис» внутри фреймворка, поэтому его можно переопределить.
Когда необходимо переопределение? Например, если вендорные библиотеки больше не поддерживают команду. Живой пример это команда doctrine:query:sql . Начиная с версии 2.2 эта команда не поддерживается и вынесена в отдельную команду dbal:run-sql.
Чтобы переопределить команду, необходимо найти её определение (definition) внутри контейнера. Делается это с помощь команды debug:container|grep «нужная вам команда или класс».
Пример для doctirne:query:sql – там используется название сервиса.
А вот для dbal:run-sql используется полное имя класса, поэтому если вдруг вы не находите название нужной вам команды, надо попробовать поискать через название класса команды.
Так пусто:
А так есть:
Когда выяснили как же называется «сервис команды», необходимо создать CompilerPass, в котором и переопределить реализацию сервиса. На примере dbal:run-sql это будет выглядеть так:
И теперь данный класс (точнее его объект) надо добавить в Kernel.php
После этого при вызове debug:container мы увидим определение для своей команды.
А вызов команды через bin/console dbal:run-sql будет теперь вызывать нашу собственную команду.
Аналогично можно сделать для команды doctrine:query:sql, но разница там будет в том, что внутри класса CompilerPass надо вставить «строку определения сервиса». Пример переопределения команды на свою собственную реализацию:
Более подробную информацию читайте в официальной документации https://symfony.com/doc/current/console.html