How to Define Commands as Services

If you're using the default services.yaml configuration, your command classes are already registered as services. Great! This is the recommended setup.

デフォルトの services.yaml 構成を使用している場合、コマンド クラスは既にサービスとして登録されています。すごい!推奨設定です。

Note

ノート

You can also manually register your command as a service by configuring the service and tagging it with console.command.

サービスを構成し、console.command でタグ付けすることにより、コマンドをサービスとして手動で登録することもできます。

For example, suppose you want to log something from within your 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
33
34
35
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
{
    private $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $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;
    }
}

If you're using the default services.yaml configuration, the command class will automatically be registered as a service and passed the $logger argument (thanks to autowiring). In other words, you only need to create this class and everything works automatically! You can call the app:sunshine command and start logging.

デフォルトの services.yaml 構成を使用している場合、コマンド クラスは自動的にサービスとして登録され、$logger 引数が渡されます (オートワイヤリングのおかげです)。つまり、このクラスを作成するだけで、すべてが自動的に機能します! app:sunshine コマンドを呼び出して、ロギングを開始できます。

Caution

注意

You do have access to services in configure(). However, if your command is not lazy, try to avoid doing any work (e.g. making database queries), as that code will be run, even if you're using the console to execute a different command.

configure() でサービスにアクセスできます。ただし、コマンドが遅延していない場合は、コンソールを使用して別のコマンドを実行している場合でも、そのコードが実行されるため、作業を行わないようにしてください (データベース クエリの作成など)。

Lazy Loading

To make your command lazily loaded, either define its name using the PHP AsCommand attribute:

コマンドを遅延ロードするには、PHPAsCommand 属性を使用してその名前を定義します。
1
2
3
4
5
6
7
8
use Symfony\Component\Console\Attribute\AsCommand;
// ...

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

Or set the command attribute on the console.command tag in your service definition:

または、サービス定義の console.command タグに command 属性を設定します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
# config/services.yaml
services:
    # ...

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

Note

ノート

If the command defines aliases (using the getAliases() method) you must add one console.command tag per alias.

コマンドが (getAliases() メソッドを使用して) エイリアスを定義する場合、エイリアスごとに 1 つの console.command タグを追加する必要があります。

That's it. One way or another, the SunshineCommand will be instantiated only when the app:sunshine command is actually called.

それでおしまい。いずれにせよ、SunshineCommand は app:sunshine コマンドが実際に呼び出されたときにのみインスタンス化されます。

Note

ノート

You don't need to call setName() for configuring the command when it is lazy.

コマンドが遅延している場合は、コマンドを構成するために setName() を呼び出す必要はありません。

Caution

注意

Calling the list command will instantiate all commands, including lazy commands.

list コマンドを呼び出すと、遅延コマンドを含むすべてのコマンドがインスタンス化されます。