默認情況下,Symfony 將會在每一個 bundle 的 Command 目錄下進行檢查并且自動登錄你的命令。如果一個命令擴展 ContainerAwareCommand,Symfony 將會甚至注入這個容器。然而為了使得這個更容易,它有一些限制:
為了解決這個問題,你可以將你的命令注冊為服務并且給它加上 console.command 的標簽:
YAML:
# app/config/config.yml
services:
app.command.my_command:
class: AppBundle\Command\MyCommand
tags:
- { name: console.command }
XML:
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="app.command.my_command"
class="AppBundle\Command\MyCommand">
<tag name="console.command" />
</service>
</services>
</container>
PHP:
// app/config/config.php
$container
->register(
'app.command.my_command',
'AppBundle\Command\MyCommand'
)
->addTag('console.command')
;
試想你想要給 name 選項一個默認值。你可以傳遞下面的一個作為 addOption() 的第五個參數(shù):
通過擴展 ContainerAwareCommand,只有第一個是可能的,由于你不能在 configure() 方法中訪問容器。作為替代,你需要注入 constructor 任何參數(shù)或者服務。舉例來說,假設你將默認值儲存在一些 %command.default_name% 參數(shù)中:
// src/AppBundle/Command/GreetCommand.php
namespace AppBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class GreetCommand extends Command
{
protected $defaultName;
public function __construct($defaultName)
{
$this->defaultName = $defaultName;
parent::__construct();
}
protected function configure()
{
// try to avoid work here (e.g. database query)
// this method is *always* called - see warning below
$defaultName = $this->defaultName;
$this
->setName('demo:greet')
->setDescription('Greet someone')
->addOption(
'name',
'-n',
InputOption::VALUE_REQUIRED,
'Who do you want to greet?',
$defaultName
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$name = $input->getOption('name');
$output->writeln($name);
}
}
現(xiàn)在,僅僅像往常一樣更新你的服務配置的參數(shù)來注入 command.default_name 參數(shù):
YAML:
# app/config/config.yml
parameters:
command.default_name: Javier
services:
app.command.my_command:
class: AppBundle\Command\MyCommand
arguments: ["%command.default_name%"]
tags:
- { name: console.command }
XML:
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="command.default_name">Javier</parameter>
</parameters>
<services>
<service id="app.command.my_command"
class="AppBundle\Command\MyCommand">
<argument>%command.default_name%</argument>
<tag name="console.command" />
</service>
</services>
</container>
PHP:
// app/config/config.php
$container->setParameter('command.default_name', 'Javier');
$container
->register(
'app.command.my_command',
'AppBundle\Command\MyCommand',
)
->setArguments(array('%command.default_name%'))
->addTag('console.command')
;
很好,你現(xiàn)在有了動態(tài)的默認值!
注意不要在 configure 中做任何工作(例如做出數(shù)據(jù)庫請求),由于你的代碼將會運行,即使你在使用控制臺執(zhí)行不同的命令。