В отличии от Laravel, в Symfony создание консольных команд доведено до абсурда. Чтобы создать заготовку команды нужно выполнить:
php bin/console generate:command MyBundle command:name
Где нужно указать имя бандла в котором будет создана команда и имя команды, по которому она будет вызываться. Если запустить generate:command без аргументов, то в интерактивном режиме будут запрошены Bundle name и Command name, а затем ещё и подтвердить всё намерение: Do you confirm generation [yes]? После чего будет создана папка src/MyBundle/Command/ (если её ещё нет) и файл в ней: src/MyBundle/Command/CommandNameCommand.php
Теперь можно вызвать свою команду так:
php bin/console command:name
Важный момент, указанный бандл уже должен существовать, иначе будет ошибка Bundle «UnknownBundle» does not exist и предложение ввести его ещё раз. Задание опций и аргументов команды аналогично тому, как это делается в Laravel. Ещё бы, ведь Laravel использует те же самые Symfony-компоненты.
Интеграция Symfony CLI с NewRelic
Если вы используете системы мониторинга типа NewRelic или подобных, то по-умолчанию запускаемые консольные скрипты будут помечаться в разделе Transactions как unknown, что сильно усложнит их мониторинг. Обойти это можно вот таким костылём: в теле метода execute каждой команды нужно перед началом выполнения дописать такие строки:
if(extension_loaded('newrelic') ) { newrelic_name_transaction($this->getName() ); }
Ленивая загрузка Symfony-команд
На самом деле не совсем понял зачем это нужно, но можно провернуть такой трюк. В методе configure команды убрать вызов setName, а для указания имени команды использовать статическое свойство $defaultName
protected static $defaultName = 'command:name';
Затем в файле config.php бандла указать:
$container ->register(\MyBundle\Command\CommandNameCommand::class) ->addTag('command.name', ['command' => \MyBundle\Command\CommandNameCommand::getDefaultName()]) ;
Однако, зачем это нужно, не совсем понял, возможно есть какой-то профит в производительности.
Доступ к сервис-контейнеру из комманды
Прокинуть зависимости в команду через конструктор не получится, так как каждая команда должна наследоваться от класса ContainerAwareCommand, который в свою очередь отнаследован от Symfony\Component\Console\Command с такой сигнатурой конструктора:
public function __construct($name = null)
Но можно делать в методе execute() команды так:
$Class = $this->getContainer()->get(Class::class);
А для получения EntityManager — так:
$EntityManager = $this->getContainer()->get('doctrine.orm.entity_manager');