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


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.

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

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