跳到內容

如何將命令定義為服務

編輯此頁面

如果您正在使用預設的 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 標籤。

就是這樣。無論哪種方式,SunshineCommand 都只會在實際呼叫 app:sunshine 命令時才被實例化。

注意

當命令是延遲載入時,您不需要呼叫 setName() 來設定命令。

警告

呼叫 list 命令會實例化所有命令,包括延遲載入的命令。但是,如果命令是 Symfony\Component\Console\Command\LazyCommand,則底層的命令工廠將不會被執行。

這項工作,包括程式碼範例,是以 Creative Commons BY-SA 3.0 授權條款授權。
目錄
    版本