Команды консоли

Команды консоли

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

Создание команды

Команды определяются в классах, которые должны быть созданы в именном пространстве Command вашего пакета (например, AppBundle\Command) и их имена должны заканчиваться суффиксом Command.

Например, команда под названием CreateUser должна следовать следующей структурe:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// src/AppBundle/Command/CreateUserCommand.php
namespace AppBundle\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class CreateUserCommand extends Command
{
    protected function configure()
    {
        // ...
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        // ...
    }
}

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// ...
protected function configure()
{
    $this
        // имя команды (часть после "bin/console")
        ->setName('app:create-user')

        // краткое описание, отображающееся при запуске "php bin/console list"
        ->setDescription('Creates a new user.')

        // полное описание команды, отображающееся при запуске команды
        // с опцией "--help"
        ->setHelp('This command allows you to create a user...')
    ;
}

Выполнение команды

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

1
$ php bin/console app:create-user

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// ...
protected function execute(InputInterface $input, OutputInterface $output)
{
    // выводит множество строк в консоль (добавляя "\n" в конце каждой строки)
    $output->writeln([
        'User Creator',
        '============',
        '',
    ]);

    // выводит сообщение с последующим "\n"
    $output->writeln('Whoa!');

    // выводит сообщение, не добавляя "\n" в конце строки
    $output->write('You are about to ');
    $output->write('create a user.');
}

Теперь, попробуйте выполнить команду:

1
2
3
4
5
6
$ php bin/console app:create-user
User Creator
============

Ух ты!
Вы на пороге создания пользователя.

Консоль ввода

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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'));
}

Теперь вы можете передать имя пользователя в команду:

1
2
3
4
5
$ php bin/console app:create-user Wouter
User Creator
============

Username: Wouter
Смотрите Console Input (Arguments & Options), чтобы узнать больше информации об опциях и аргументах консоли.

Получение сервисов и сервис-контейнера

Чтобы действительно создать новго пользователя, команда должна получить доступ к некоторым сервисам. Это может быть сделано путем расширения командой класса ContainerAwareCommand:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// ...
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;

class CreateUserCommand extends ContainerAwareCommand
{
    // ...

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        // ...

        // получить доступ к контейнеру, используя getContainer()
        $userManager = $this->getContainer()->get('app.user_manager');
        $userManager->create($input->getArgument('username'));

        $output->writeln('User successfully generated!');
    }
}

Теперь, когда вы создали необходимые сервисы и логику, команда будет выполнять метод create() сервиса app.user_manager и пользователь будет создан.

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

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

initialize() (необязательный)
Этот метод выполняется до методов interact() и 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
37
// tests/AppBundle/Command/CreateUserCommandTest.php
namespace Tests\AppBundle\Command;

use AppBundle\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()
    {
        self::bootKernel();
        $application = new Application(self::$kernel);

        $application->add(new CreateUserCommand());

        $command = $application->find('app:create-user');
        $commandTester = new CommandTester($command);
        $commandTester->execute(array(
            'command'  => $command->getName(),

            // передать аргументы в помощник
            'username' => 'Wouter',

            // использовать префик из двух длинных тире перед ключом,
            // при передаче опций
            // например: '--some-option' => 'option_value',
        ));

        // вывод команды в консоли
        $output = $commandTester->getDisplay();
        $this->assertContains('Username: Wouter', $output);

        // ...
    }
}

Tip

Вы также можете тестировать всю консоль приложения, используя ApplicationTester.

Note

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

Чтобы иметь возможность использовать полностью установленный сервис-контейнер для тестов вашей консоли, вы можете расширить ваш тест из KernelTestCase:

 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
// ...
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

class CreateUserCommandTest extends KernelTestCase
{
    public function testExecute()
    {
        $kernel = static::createKernel();
        $kernel->boot();

        $application = new Application($kernel);
        $application->add(new CreateUserCommand());

        $command = $application->find('app:create-user');
        $commandTester = new CommandTester($command);
        $commandTester->execute(array(
            'command'  => $command->getName(),
            'username' => 'Wouter',
        ));

        $output = $commandTester->getDisplay();
        $this->assertContains('Username: Wouter', $output);

        // ...
    }
}

Узнать больше

Компонент консоль акже содержит набор "помощников" - разных маленьких инструментов, способных помочь вам с разными заданиями:

  • Question Helper: узнать у пользователя информацию в диалоговом режиме
  • Formatter Helper: настроить расцвеичвание вывода
  • Progress Bar: показать бар прогресса
  • Table: отобразить данные в табличной форме

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.