这个组件部分的Console页面(Console组件)介绍了如何创建一个Console Command。这篇文章涉及到在symfony框架中创建console commands。
自动注册Commands
为了能使symfony中的Console commands自动有效,来在你的bundle中创建一个Command目录并为每个Command创建一个php文件Command.php。例如,如果你想扩展AppBundle去生成你自己的命令行,创建GreetCommand.php并添加如下代码:
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 36 37 38 39 40 41 42 43 44 45 46 |
// src/AppBundle/Command/GreetCommand.php namespace AppBundle\Command; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class GreetCommand extends ContainerAwareCommand { protected function configure() { $this ->setName('demo:greet') ->setDescription('Greet someone') ->addArgument( 'name', InputArgument::OPTIONAL, 'Who do you want to greet?' ) ->addOption( 'yell', null, InputOption::VALUE_NONE, 'If set, the task will yell in uppercase letters' ) ; } protected function execute(InputInterface $input, OutputInterface $output) { $name = $input->getArgument('name'); if ($name) { $text = 'Hello '.$name; } else { $text = 'Hello'; } if ($input->getOption('yell')) { $text = strtoupper($text); } $output->writeln($text); } } |
现在,这个命令已经提供了,并可以运行:
1 |
$ php bin/console demo:greet Fabien |
在服务容器中注册Command
就像控制器,命令可以声明为服务。请查看 dedicated cookbook entry了解更多详情。
从服务容器中获取服务
通过使用 ContainerAwareCommand这个基类作为command(而不是基于command),你可以直接访问服务容器。换句话说,你可以访问任何配置的服务:
1 2 3 4 5 6 7 8 |
protected function execute(InputInterface $input, OutputInterface $output) { $name = $input->getArgument('name'); $logger = $this->getContainer()->get('logger'); $logger->info('Executing command for '.$name); // ... } |
调用其它命令
Calling an Existing Command,如果你需要去实现运行一个命令,并关联其他命令。
测试命令
当使用的测试命令作为框架的一部分,Symfony\Bundle\FrameworkBundle\Console\Application应该替代Symfony\Component\Console\Application
:
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 |
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Bundle\FrameworkBundle\Console\Application; use AppBundle\Command\GreetCommand; class ListCommandTest extends \PHPUnit_Framework_TestCase { public function testExecute() { // mock the Kernel or create one depending on your needs $application = new Application($kernel); $application->add(new GreetCommand()); $command = $application->find('demo:greet'); $commandTester = new CommandTester($command); $commandTester->execute( array( 'name' => 'Fabien', '--yell' => true, ) ); $this->assertRegExp('/.../', $commandTester->getDisplay()); // ... } } |
在特殊情况下,这个name参数和这个–yell选项不是强制性让命令去工作,但在显示时,你可以看到调用命令时如何自定义他们。
为了能够在你的console test中使用全部服务容器,你能够从KernelTestCase中继承你的测试:
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 |
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use AppBundle\Command\GreetCommand; class ListCommandTest extends KernelTestCase { public function testExecute() { $kernel = $this->createKernel(); $kernel->boot(); $application = new Application($kernel); $application->add(new GreetCommand()); $command = $application->find('demo:greet'); $commandTester = new CommandTester($command); $commandTester->execute( array( 'name' => 'Fabien', '--yell' => true, ) ); $this->assertRegExp('/.../', $commandTester->getDisplay()); // ... } } |