Як визначати команди, як сервіси

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

Як визначати команди, як сервіси

Якщо ви використовуєте конфігурацію services.yaml за замовчуванням , то ваші класи команд вже зареєстровані як сервіси. Чудово! Це рекомендована установка.

Note

Ви також можете вручну зарєструквати вашу команду як сервіс, сконфігурувавши сервіс та тегувавши його за допомогою console.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
25
26
27
28
29
30
31
32
namespace App\Command;

use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'app:sunshine')]
class SunshineCommand extends Command
{
    public function __construct(
        private LoggerInterface $logger,
    ) {
        // ви *повинні* викликати батьківський конструктор
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->setDescription('Good morning!');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $this->logger->info('Waking up the sun');
        // ...

        return Command::SUCCESS;
    }
}

Якщо ви використовуєте конфігурацію services.yaml за замовчуванням , то клас команди автоматично буде зареєстровано як сервіс і передано аргументу $logger (завдяки автомонтуванню). Іншими словами, просто створивши цей клас - все працює! Ви можете викликати команду app:sunshine і почати вести запис логів.

Caution

У вас є доступ до сервісів configure(). Однак, якщо ваша команда не лінива , спробуйте уникати будь-якої роботи (наприклад, запити у БД), так як цей код буде виконано, навіть якщо ви використовуєте консоль для виконання іншої команди.

Ліниве завантаження

Щоб зробити вашу команду ліниво завантажуваною, або визнчте її імʼя, використовуючи PHP-атрибут AsCommand:

1
2
3
4
5
6
7
8
use Symfony\Component\Console\Attribute\AsCommand;
// ...

#[AsCommand(name: 'app:sunshine')]
class SunshineCommand extends Command
{
    // ...
}

Або встановіть атрибут command у тегу console.command у вашому визначенні сервісу:

1
2
3
4
5
6
7
# config/services.yaml
services:
    # ...

    App\Command\SunshineCommand:
        tags:
            - { name: 'console.command', command: 'app:sunshine' }

Note

Якщо команда визначає псевдоніми (використовуючи метод getAliases()), ви повинні додати по одному тегу console.command на псевдонім.

Ось і все. Так чи інакше, SunshineCommand буде інстаційована лише тоді, коли команда app:sunshine буде дійсно викликана.

Note

Вам не потрібно викликати setName() для конфігурації команди, якщо вона лінива.

Caution

Виклик команди list призведе до інстанціювання усіх команд, включно з лінивими командами. Однак, якщо команда - це Symfony\Component\Console\Command\LazyCommand, то базову фабрику команд не буде виконано.