跳到内容

如何将命令定义为服务

编辑此页

如果您正在使用 默认的 services.yaml 配置,您的命令类已经被注册为服务。太棒了!这是推荐的设置。

注意

您也可以通过配置服务并使用 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,
    ) {
        // you *must* call the parent constructor
        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 命令并开始记录日志。

警告

您在 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
{
    // ...
}

或者在您的服务定义中,在 console.command 标签上设置 command 属性

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

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

注意

如果命令定义了别名(使用 getAliases() 方法),您必须为每个别名添加一个 console.command 标签。

就是这样。无论如何,只有在实际调用 app:sunshine 命令时,才会实例化 SunshineCommand

注意

当命令是懒加载时,您不需要调用 setName() 来配置命令。

警告

调用 list 命令将实例化所有命令,包括懒加载命令。但是,如果命令是 Symfony\Component\Console\Command\LazyCommand,则不会执行底层的命令工厂。

本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本