如何將命令定義為服務
如果您正在使用預設的 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\
,則底層的命令工廠將不會被執行。