Консольные команды в Symfony 4

Фремворк Symfony предоставляет множество консольных команд через скрипт bin/console (например, хорошо известная всем команда для очистки кеша bin/console cache:clear). Эти команды создаются с помощью компонента Console. Вы также можете использовать его для создания своих собственных команд.

Консоль: APP_ENV и APP_DEBUG

Консольные команды выполняются в окружении, определенном в переменной APP_ENV файла .env, по умолчанию установлено значение dev. Также читается значение переменной APP_DEBUG, чтобы включать или отключать режим «отладки» (по умолчанию установлено 1, что значит режим отладки включен).

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

Создание консольных команд

Консольные команды определяются в классах, расширяющих базовый класс Command. Например, вы можете захотеть команду для создания пользователя:

Конфигурация команд

Первое, что следует сделать, это дать описание новой консольной команды в методе configure(). Затем вы можете опционально определить сообщение для справки о команде, а также установить входные параметры и аргументы:

// ... protected function configure() { $this // краткое описание команды, отображаемое при запуске "php bin / console list" ->setDescription('Creates a new user.') // полное описание команды, отображаемое при запуске команды с параметром --help ->setHelp('This command allows you to create a user...') ; }

Метод configure() вызывается автоматически в конце конструктора команд. Если ваша команда определяет свой собственный конструктор, сначала установите свойства, а затем вызовите родительский конструктор, чтобы эти свойства были доступны в методе configure():

requirePassword = $requirePassword; parent::__construct(); } public function configure() { $this // ... ->addArgument('password', $this->requirePassword ? InputArgument::REQUIRED : InputArgument::OPTIONAL, 'User password') ; } }

Регистрация консольных команд

Консольные команды в Symfony 4 должны быть зарегистрированы как Сервисы и помечены тегом console.command. Если вы используете конфигурацию в файле services.yaml по умолчанию, это уже сделано для вас, благодаря автоконфигурации.

Выполнение (запуск) команд

После конфигурирования и регистрации команды вы можете выполнить ее в терминале:

php bin/console app:create-user

Разумеется сейчас, эта команда ничего не сделает, так как вы еще не написали никакой логики. Добавлять свою собственную логику следует в методе execute ().

Вывод информации в консоль

Метод execute() имеет доступ к потоку вывода для записи сообщений в консоль:

// ... protected function execute(InputInterface $input, OutputInterface $output) { // выводит в консоль несколько строк (добавляя "\n" в конце каждой строки) $output->writeln([ 'User Creator', '============', '', ]); // значение, возвращаемое методом someMethod(), может быть итератором (https://secure.php.net/iterator), // который генерирует и возвращает сообщения с PHP-ключом "yield" $output->writeln($this->someMethod()); // выводит сообщение, сопровождаемое "\n" (с новой строки) $output->writeln('Whoa!'); // выводит сообщение без добавления "\n" к концу строки // (строки будут выводиться одна за другой) $output->write('You are about to '); $output->write('create a user.'); }

Если сейчас выполнить, эту консольную команду, то выведет:

php bin/console app:create-user 
User Creator
============

Whoa!
You are about to create a user.

Секции вывода

Стандартный вывод консоли можно разделить на несколько независимых областей, называемых «секции вывода». Создайте один или несколько из таких секций, когда вам нужно очистить и перезаписать выходную информацию.

Секции создаются с помощью метода section(), который возвращает экземпляр ConsoleSectionOutput:

//.......... class MyCommand extends Command { //......... protected function execute(InputInterface $input, OutputInterface $output) { $section1 = $output->section(); $section2 = $output->section(); $section1->writeln('Hello'); $section2->writeln('World!'); // вывод отображает "Hello\nWorld!\n" // метод overwrite() заменяет всё содержимое указанной секции новым указанным текстом $section1->overwrite('Goodbye'); // теперь будет вывод "Goodbye\nWorld!\n" // метод clear() удаляет весь контент, указанной секции $section2->clear(); // Теперь будет вывод "Goodbye\n" // ...но вы можете указать сколько строк в секции удалить // (пример ниже удаляет 2 последних строки у указанной секции) $section1->clear(2); // Вывод консоли теперь пустой! } }

Новая строка добавляется автоматически при отображении информации в секции.


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

Ввод информации в консоль

Используйте входные параметры или аргументы для передачи информации в консольную команду:

//...... use Symfony\Component\Console\Input\InputArgument; // ... protected function configure() { $this // конфигурация аргумента ->addArgument('username', InputArgument::REQUIRED, 'The username of the user.') // ... ; } // ... public function execute(InputInterface $input, OutputInterface $output) { $output->writeln([ 'User Creator', '============', '', ]); // получение значение входного аргумента, используя метод getArgument() $output->writeln('Username: '.$input->getArgument('username')); }

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

php bin/console app:create-user Wouter
User Creator
============

Username: Wouter

Для получения дополнительной информации о входных параметрах и аргументах консоли, прочитайте статью консоль ввода (аргументы и параметры).


Получение Сервисов из Сервис-Контейнера.

На практике, чтобы создать нового пользователя, консольная команда в Symfony 4 должна получить доступ к различным Сервисам. Поскольку ваша команда уже зарегистрирована как сервис, вы можете использовать обычную инъекцию зависимостей. Представьте, что у вас есть сервис App\Service\UserManager, к которой вы хотите получить доступ:

// … use Symfony\Component\Console\Command\Command; use App\Service\UserManager; class CreateUserCommand extends Command { private $userManager; public function __construct(UserManager $userManager) { $this->userManager = $userManager; parent::__construct(); } // … protected function execute(InputInterface $input, OutputInterface $output) { // … $this->userManager->create($input->getArgument(‘username’)); $output->writeln(‘User successfully generated!’); } }

Жизненный цикл консольной команды

Консольные команды в Symfony имеют три метода жизненного цикла, которые вызываются при запуске команды:

  • initialize() (необязательный). Этот метод выполняется перед методами interact() и the execute(). Его основная цель — инициализировать переменные, используемые в остальных методах консольной команды.
  • interact() (необязательный). Этот метод выполняется после initialize() и перед execute(). Его цель — проверить, отсутствуют ли какие-либо параметры/аргументы, и в интерактивном режиме запросить у пользователя эти значения. Это последнее место, где вы можете запросить отсутствующие параметры/аргументы. После этой команды пропущенные параметры/аргументы приведут к ошибке.
  • execute() (обязательный). Этот метод выполняется после выполнения interact() и initialize (). Он содержит логику, которую вы хотите выполнять в консольной команде.

Тестирование консольных команд

Symfony предоставляет несколько инструментов, помогающие вам тестировать ваши консольные команды. Наиболее полезным является класс CommandTester. Он использует специальные классы ввода и вывода для облегчения тестирования без реальной консоли:

find('app:create-user'); $commandTester = new CommandTester($command); $commandTester->execute([ 'command' => $command->getName(), // передача аргументов хелперу 'username' => 'Wouter', // при передаче параметров ставим перед ключом две черточки,             // например: '--some-option' => 'option_value', ]); // вывод результата работы команды в консоль $output = $commandTester->getDisplay(); $this->assertContains('Username: Wouter', $output); // ... } }

Вы также можете протестировать целое консольное приложение с помощью ApplicationTester.

При использовании компонента Console в автономном проекте используйте Symfony\Component\Console\Application и расширьте обычный \PHPUnit\Framework\TestCase.

Логирование ошибок консольных команд

Всякий раз, когда возникает исключение во время выполнения консольных команд, Symfony добавляет для него сообщение в лог, включая всю неудачную команду. Кроме того, Symfony регистрирует подписчика на событие для прослушивания события ConsoleEvents::TERMINATE и добавляет сообщение в лог, когда команда не завершает работу со статусом выхода 0.

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

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