Console Component命令行组件在Symfony 3.2中获得了极大提升,多数都是关乎DX开发体验改进的(developer experience)。本文是console系列第一篇,将讨论这些新功能中的四个。
命令假名将不再作为独立命令显示 ¶
在最佳实践中,我们推荐把命令“命名空间化”,以避免冲突,同时改进程序的组织性。但是,对于频繁使用的命令,还是定义快捷方式更方便:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class VeryLongNameCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName('app:very:long:name')
->setDescription('Lorem Ipsum...')
// ...
->setAliases(['foo'])
;
}
// ...
} |
上例中,命令既能以./bin/console app:very:long:name
来执行,也能以./bin/console foo
执行。虽然只是一条命令,但Symfony将以两个单独的命令来呈现。
1 2 3 4 5 6 | $ ./bin/console
Available commands:
foo Lorem Ipsum...
app:
app:very:long:name Lorem Ipsum... |
在Symfony 3.2中,假名被包含在原始命令的“行内”,减轻了命令行输出的卡顿:
1 2 3 4 5 | $ ./bin/console
Available commands:
app:
app:very:long:name [foo] Lorem Ipsum... |
静默模式中仍然显示错误 ¶
当运行一个Symfony命令时,如果你添加了-q
或--quiet
选项,那么输出(output)将被配置为OutputInterface::VERBOSITY_QUIET
级别。此举会令命令行不输出任何信息,包括报错信息。
在Symfony 3.2中我们改进了-q
和--quiet
选项,抑制了Logger::ERROR
级别日志信息之外的全部信息。这样你就不会再遗失任何错误信息了。
对单一命令程序提供更好的支持 ¶
用Symfony构建单一命令程序(single command application)是可能的,但是需要你做出一些改变,以避免持续传入命令的名字。在Symfony 3.2中,我们改进了Application
基类,以更好地支持单一命令程序。
首先,像以前一样定义一个命令,而创建console程序。然后,设置一个唯一的命令作为默认命令,并传递true
作为setDefaultCommand()
的第二个参数。它能把程序转换成一个“单一命令程序”。
1 2 3 4 5 6 7 8 9 10 11 12 13 | use Symfony\Component\Console\Application;
$command = new \FooCommand();
$application = new Application();
$application->add($command);
// the second boolean argument tells if this is a single-command app
// 第二个布尔值参数,指明这是否是一个单一命令程序
$application->setDefaultCommand($command->getName(), true);
// this now executes the 'FooCommand' without passing its name
// 现在执行“FooCommand”时不需传入该命令的名称
$application->run(); |
简化了命令行的测试 ¶
测试一个Symfony命令可谓是“不必要的复杂”,而且需要你深入到PHP的stream中。例如,你的测试需要模拟一个用户输入123
、foo
和bar
,那么你要用到下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | use Symfony\Component\Console\Tester\CommandTester;
$commandTester = new CommandTester($command);
$helper = $command->getHelper('question');
$helper->setInputStream($this->getInputStream("123\nfoo\nbar\n"));
protected function getInputStream($input)
{
$stream = fopen('php://memory', 'r+', false);
fputs($stream, $input);
rewind($stream);
return $stream;
} |
在Symfony 3.2中,我们简化了命令测试,通过添加一个全新的setInputs()
方法到CommandTester
这个helper中。你只需把用户键入的“内容数组”传入即可:
1 2 3 4 | use Symfony\Component\Console\Tester\CommandTester;
$commandTester = new CommandTester($command);
$commandTester->setInputs(['123', 'foo', 'bar']); |