Deprecated: Function create_function() is deprecated in /home/worldhel/public_html/wp-content/plugins/codecolorer/lib/geshi.php on line 4698
Фремворк Symfony предоставляет множество консольных команд через скрипт bin/console (например, хорошо известная всем команда для очистки кеша bin/console cache:clear). Эти команды создаются с помощью компонента Console. Вы также можете использовать его для создания своих собственных команд.
Консоль: APP_ENV и APP_DEBUG
Консольные команды выполняются в окружении, определенном в переменной APP_ENV файла .env, по умолчанию установлено значение dev. Также читается значение переменной APP_DEBUG, чтобы включать или отключать режим «отладки» (по умолчанию установлено 1, что значит режим отладки включен).
Чтобы запустить консольную команду в другом окружении или в другом режиме отладки, измените значения переменных APP_ENV и APP_DEBUG.
Создание консольных команд
Консольные команды определяются в классах, расширяющих базовый класс Command. Например, вы можете захотеть команду для создания пользователя:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php // src/Command/CreateUserCommand.php namespace App\Command; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class CreateUserCommand extends Command { // название команды (это часть после "bin/console") protected static $defaultName = 'app:create-user'; protected function configure() { // ... } protected function execute(InputInterface $input, OutputInterface $output) { // ... } } |
Конфигурация команд
Первое, что следует сделать, это дать описание новой консольной команды в методе configure(). Затем вы можете опционально определить сообщение для справки о команде, а также установить входные параметры и аргументы:
1 2 3 4 5 6 7 8 9 10 11 | // ... 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():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?php use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; class CreateUserCommand extends Command { // ... public function __construct(bool $requirePassword = false) { // лучшие практики рекомендуют сначала вызвать родительский конструктор и // затем устанавливаем ваши собственные свойства. Но это не сработает в этом случае, // потому что методу configure() требуются свойства, установленные в этом конструкторе $this->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() имеет доступ к потоку вывода для записи сообщений в консоль:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // ... 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | //.......... 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); // Вывод консоли теперь пустой! } } |
Новая строка добавляется автоматически при отображении информации в секции.
Секции вывода позволяют управлять выводом в консоль расширенными способами, такими как отображение нескольких прогресс-баров выполнения, которые обновляются независимо, и добавление строк в таблицы, которые уже были отрисованы.
Ввод информации в консоль
Используйте входные параметры или аргументы для передачи информации в консольную команду:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | //...... 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. Он использует специальные классы ввода и вывода для облегчения тестирования без реальной консоли:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <?php // tests/Command/CreateUserCommandTest.php namespace App\Tests\Command; use App\Command\CreateUserCommand; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Console\Tester\CommandTester; class CreateUserCommandTest extends KernelTestCase { public function testExecute() { $kernel = static::createKernel(); $application = new Application($kernel); $command = $application->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.