Symfony Console CommandsをSymfony DependencyInjection Componentを使用してServiceとして実行する方法の備忘録です。
DIを使用することでCommandのテストでモックを使用できます。
Symfony 4.4を使用しています。
2021年11月12日時点の最新である5.3ではないことに注意してください。
--path/to/project
|
|-- bin
|
|-- console
|
|-- config
|
|-- service.yml
|
|-- src
|
|-- Command
|
|-- MessageCommand.php
|
|-- Service
|
|-- MessageGenerator.php
|
|-- composer.json
必要なコンポーネントをインストールします。
$ composer req symfony/console:^4.4
$ composer req symfony/dependency-injection:^4.4
$ composer req symfony/config:^4.4
$ composer req symfony/yaml:^4.4
※ 一般にはcomposer init
でcomposer.json
を作成しますが、本記事は簡単化のため上記の方法で進めます。
今回作成するアプリの名前空間はFoo\Console\
として進めます。
"autoload": {
"psr-4": {
"Foo\\Console\\": "src/"
}
},
autoload.php
を更新します。
$ composer dump-autoload
<?php
namespace Foo\Console\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class MessageCommand extends Command
{
const NAME = 'command:message';
private $messageGenerator;
public function __construct($messageGenerator)
{
parent::__construct(self::NAME);
$this->messageGenerator = $messageGenerator;
}
protected function configure()
{
$this->addUsage('挨拶を表示');
$this->addArgument(
'message',
InputArgument::REQUIRED,
'Message for display'
);
$this->addOption(
'name',
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'first name, last name',
['foo']
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$message = $input->getArgument('message');
$name = $input->getOption('name');
$output->writeln($this->messageGenerator->getMessage($message, $name));
return 0;
}
}
<?php
namespace Foo\Console\Service;
class MessageGenerator {
public function getMessage(string $message, array $name): string
{
return sprintf('%s! %sさん', $message, implode(' ', $name));
}
}
config/service.yml
でServiceを定義します。
services:
message.generator:
class: Foo\Console\Service\MessageGenerator
# command
command.message:
class: Foo\Console\Command\MessageCommand
arguments:
$messageGenerator: '@message.generator'
# app
app:
class: Symfony\Component\Console\Application
calls:
- add: ['@command.message']
public: true
bin/consoleファイルを作成して実行権を付与します。
$ mkdir bin
$ touch bin/console
$ chmod u+x bin/console
bin/console
でコンテナビルダーを使ってSymfony Console Commandsをサービスとして実行します。
#!/usr/bin/env php
<?php
require __DIR__ . '/../vendor/autoload.php';
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
$containerBuilder = new ContainerBuilder();
$loader = new YamlFileLoader($containerBuilder, new FileLocator(__DIR__));
$loader->load(__DIR__ . '/../config/services.yaml');
$containerBuilder->compile(true);
$application = $containerBuilder->get('app');
$application->run();
$ bin/console command:message "Hello World" --name=Hiroshi --name=Sawai
//Hello! Hiroshi Sawaiさん
No comments yet.
改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。