Как определять команды, как сервисы
Как определять команды, как сервисы
Если вы используете конфигурацию services.yaml по умолчанию , то ваши классы команд уже зарегистрированы, как сервисы. Отлично! Это рекомендованная установка.
Note
Вы также можете вручную зарегистрировать вашу команду, как сервис, сконфигурировав
сервис и тегировав его с помощью console.command
.
В любом случае, если ваш класс расширяет ContainerAwareCommand,
то вы можете получить доступ к публичным сервисам через $this->getContainer()->get('SERVICE_ID')
.
Но если ваш класс зарегистрирован, как сервис, вы можете вместо этого получить доступ к сервисам, используя нормальное внедрение зависимости .
Например, представьте, что вы хотите записать лог чего-либо изнутри вашей команды:
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\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class SunshineCommand extends Command
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
// вы *должны* вызвать родительский конструктор
parent::__construct();
}
protected function configure()
{
$this
->setName('app:sunshine')
->setDescription('Good morning!');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->logger->info('Waking up the sun');
// ...
}
}
Если вы используете конфигурацию services.yaml по умолчанию ,
то класс команды автоматически будет зарегистрирован, как сервис, и передан аргументу $logger
(благодаря автомонтированию). Другими словами, просто создав этот класс, всё работает!
Вы можете вызвать команду app:sunshine
и начать вести запись логов.
Caution
У вас есть достут к серверам configure()
. Однако, если ваша команда не
ленивая , попробуйте избегать любой
работы (например, запросы в DB), так как этот код будет выполнен, даже если вы
используете консоль для выполнения другой комнады.
Ленивая загрузка
Чтобы сделать вашу команду лениво загружаемой, определите её статичное свойство $defaultName
:
1 2 3 4 5 6
class SunshineCommand extends Command
{
protected static $defaultName = 'app:sunshine';
// ...
}
Или установите атрибут command
в теге console.command
в вашем определении сервиса:
- YAML
- XML
- PHP
1 2 3 4 5 6
# config/services.yaml
services:
App\Command\SunshineCommand:
tags:
- { name: 'console.command', command: 'app:sunshine' }
# ...
Вот и всё. Так или иначе, SunshineCommand
будет инстанциирована только тогда,
когда команда app:sunshine
будет действительно вызвана.
Note
Вам не нужно вызывать setName()
для конфигуриации команды, если она ленивая.
Caution
Вызов команды list
инстанциирует все команды, включая ленивые.