Как определять команды, как сервисы
Дата обновления перевода 2024-07-16
Как определять команды, как сервисы
Если вы используете конфигурацию 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()
. Однако, если ваша команда не
ленивая , попробуйте избегать любой
работы (например, запросы в DB), так как этот код будет выполнен, даже если вы
используете консоль для выполнения другой комнады.
Ленивая загрузка
Чтобы команда загружалась лениво, либо определите ее имя с помощью атрибута 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
, то
базовая фабрика команд не будет выполнена.