Дата оновлення перекладу 2022-05-10

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

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

Консоль: APP_ENV і APP_DEBUG

Консольні команди виконуються в середовищі, визначеному у змінній APP_ENV файлу .env, за замовчуванням - dev. Він також зчитує значення APP_DEBUG, щоб вмикати і вимикати режим “налагодження” (за замовчуванням - 1, тобто увімкнено).

Щоб запустити команду в іншому середовищі або режимі налагодження, відредагуйте значення APP_ENV і APP_DEBUG.

Створення команди

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

// 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(): void
    {
        // ...
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        // ... введіть тут код, щоб створити користувача

        // цей метод має повернути ціле число з "кодом завершення"
        // команди. Ви також можете використовувати ці константи, щоб зробити код більш читаним

        // повернути це, якщо при виконанні команди не було проблем
        // (рівноцінно поверненню int(0))
        return Command::SUCCESS;

        // або повернути це, якщо під час виконання виникла помилка
        // (рівноцінно поверненню int(1))
        // return Command::FAILURE;

        // або повернути це, щоб вказати на неправильне використання команди, наприклад, невалідні опції
        // або відсутні аргументи (рівноцінно поверненню int(2))
        // return Command::INVALID
    }
}

New in version 5.1: Константи Command::SUCCESS та Command::FAILURE були представлені в Symfony 5.1.

New in version 5.3: Константа Command::INVALID була представлена в Symfony 5.3

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

Ви можете за бажанням визначити опис, повідомлення допомоги і аргументи та опції введення:

// ...
// опис команди, що відображається при запуску "php bin/console list"
protected static $defaultDescription = 'Creates a new user.';

// ...
protected function configure(): void
{
    $this
        // Якщо вам не подобається використовувати статичну властивість $defaultDescription,
        // ви також можете визначати короткий опис, використовуючи цей метод:
        // ->setDescription('...')

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

Визначення статичної властивості $defaultDescription замість використання методу setDescription(), дозволяє отримувати опис команди без інстанціювання її класу. Це робить виконання команди php bin/console list значно швидшим.

Якщо ви хочете завжди швидко виконувати команду list, додайте до неї опцію --short (php bin/console list --short). Таким чином ви уникнете інстанціювання класів команди, але і не будете отримувати відображення опису команд, які використовують метод setDescription() замість статичної властивості.

New in version 5.3: Статична властивість $defaultDescription та опція --short були представлені в Symfony 5.3.

Метод configure() викликається автоматично наприкінці конструктору команди. Якщо ваша команда визначає свій конструктор, спочатку встановіть властивості та викликчте батьківський конструктор для того, щоб ці властивості стали доступні в методі configure():

// ...
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();
    }

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

Реєстрація команди

Команди Symfony мають бути зареєстровані як сервіси та відмічені тегом console.command. Якщо ви використовуєте кофігурацію services.yaml за замовчуванням, це вже зроблено для вас, завдяки автоконфігурації.

Виконання команди

Після налаштування та реєстрації команди ви можете виконати її в терміналі:

1
$ 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('Ух ти!');

    // виводить повідомлення, не додаючи "\n" наприкінці рядку
    $output->write('Ви вже майже');
    $output->write('створили користувача.');
}

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

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

Ух ти!
Ви вже майже створили користувача.

Секції виведення

New in version 4.1: Секції виведення з’явилися в Symfony 4.1.

Звичайне виведення консолі може бути розділене на декілька незалежних регіонів під назвою “секції виведення”. Створіть одну або декілька таких секцій, коли вам потрібно очистити та перезаписати інформацію, що виводиться.

Секції створюються методом ConsoleOutput::section(), який повертає екземпляр ConsoleSectionOutput:

// ...
use Symfony\Component\Console\Output\ConsoleOutputInterface;

class MyCommand extends Command
{
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        if (!$output instanceof ConsoleOutputInterface) {
            throw new \LogicException('Эта команда принимает только экземпляр "ConsoleOutputInterface".');
        }

        $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"

        // ...але ви також можете видалити задану кількість рядків
        // (цей приклад видаляє два останні рядки секції)
        $section1->clear(2);
        // Тепер виведення абсолютно пусте!

        return Command::SUCCESS;
    }
}

Note

Новий рядок додається автоматично при відображенні інформації в секції.

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

Введення в консоль

Використовуйте опції або аргументи введення, щоб передати інформацію в команду:

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

See also

Дивіться Console Input (Arguments & Options), щоб дізнатися більше інформації про опції та аргументи консолі.

Отримання сервісів та сервіс-контейнера

Щоб дійсно створити нового користувача, команда має отримати доступ до деяких сервісів. Так як ваша команда вже зареєстрована як сервіс, ви можете використовувати нормальне впровадження залежності. Уявіть, що у вас є сервіс App\Service\UserManager, до якого ви хочете отримати доступ:

// ...
use App\Service\UserManager;
use Symfony\Component\Console\Command\Command;

class CreateUserCommand extends Command
{
    private $userManager;

    public function __construct(UserManager $userManager)
    {
        $this->userManager = $userManager;

        parent::__construct();
    }

    // ...

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

        $this->userManager->create($input->getArgument('username'));

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

        return Command::SUCCESS;
    }
}

Життєвий цикл команди

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

initialize() (необов’язковий)
Цей метод виконується до методів interact() та execute(). Його головна ціль - ініціалізувати змінні, які використовуються в інших методах команди.
interact() (необов’язковий)
Цей метод виконується після initialize() і до execute(). Його ціль - перевірка наявності всіх опцій/аргументів, та запитати у користувача значення в діалоговому режимі. Це останнє місце, де ви можете запитати відсутні опції/аргументи. Після цієї команди, відсутні опції/аргументи будуть призводити до помилки.
execute() (обов’язковий)
Цей метод виконується післе``interact()`` та initialize(). Він містить логіку, яку ви хочете виконати за допомогою команди.

Тестування команд

Symfony надає декілька інструментів, щоб допомогти вам тестувати ваші команди. Найкорисніший - це клас CommandTester. Він використовує спеціальні класи введення та виведення, щоб полегшити тестування без справжньої консолі:

// tests/Command/CreateUserCommandTest.php
namespace App\Tests\Command;

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

        $command = $application->find('app:create-user');
        $commandTester = new CommandTester($command);
        $commandTester->execute([
            // передати аргументи хелперу
            'username' => 'Wouter',

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

        $commandTester->assertCommandIsSuccessful();

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

        // ...
    }
}

Якщо ви використовуєте додаток однієї команди, викличте setAutoExit(false), щоб отримати результат комнади в CommandTester.

New in version 5.2: Метод setAutoExit() для додатків однієї команди був представлений в Symfony 5.2.

New in version 5.4: Метод assertCommandIsSuccessful() був представлений в Symfony 5.4.

Tip

Ви також можете тестувати всю консоль додатку, використовуючи ApplicationTester.

Caution

При тестуванні команд з використанням класу CommandTester, події консолі не запускаються. Якщо вам потрібно протестувати ці події, використовуйте замість цього ApplicationTester.

Caution

При тестуванні команд з використанням класу ApplicationTester, не забудьте відключити автоматичний вихід:

$application = new Application();
$application->setAutoExit(false);

$tester = new ApplicationTester($application);

Note

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

Ведення логів помилок команди

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

Дізнайтеся більше

Компонент Консоль також містить набір “хелперів” - різних маленьких інструментів, здатних допомогти вам з різними завданнями:

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

налагоджування при запуску зовнішньої програми * Cursor Helper: дозволяє маніпулювати курсором в терміналі

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