看一眼你为自己的Symfony程序所开发的任何一个“命令行”代码。很大概率是,代码“一团糟”——混合着内容和表现层。例如,为了显示命令行的output的标题,你可能使用了下面几种常见方法之一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // alternative 1 方案1
$formatter = $this->getHelperSet()->get('formatter');
$formattedBlock = $formatter->formatBlock('Lorem Ipsum Dolor Sit Amet', '', true);
$output->writeln($formattedBlock);
// alternative 2 方案2
$title = 'Lorem Ipsum Dolor Sit Amet';
$output->writeln('<info>'.$title.'</info>');
$output->writeln(str_repeat('=', strlen($title)));
// alternative 3 方案3
$output->writeln('');
$output->writeln('<info>Lorem Ipsum Dolor Sit Amet</>');
$output->writeln('<info>-- -- -- -- -- -- --</>');
$output->writeln(''); |
几个月之前,我们决定改善这种情形,办法是引入一个全新的Symfony命令行样式向导(style guide)。样式已经在Symfony2.7中可用,但我们真正开始使用它们还是在2.8中。用一个网络程序进行类比,这些样式允许你创建语义化、忘掉其样式及行为的console命令。好比你的命令只需定义“HTML”,然后样式向导就是把它转化成现实的“bootstrap和jquery”。
在command程序中使用这个新的样式向导是相当容易的,实例化SymfonyStyle
类,把你命令的$input
和$output
传给它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | namespace AppBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
class MyCommand extends ContainerAwareCommand
{
protected function configure()
{
// ...
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
// ...
}
} |
我们推荐你把这个变量命名为$io
,因为你既可以在input也可以在output操作中使用它。依上面例程,以下演示了如何在你的命令中输出一个标题:
1 | $io->title('Lorem Ipsum Dolor Sit Amet'); |
Symfony会帮你照顾样式细节:它会改变字体颜色,还能在标题的前后添加一个新行(new line),并对标题显示下划线。
样式向导包括了大量常用的快捷方法,例如要显示一个表格时:
1 2 3 4 5 6 7 | $headers = ['Parameter', 'Value'];
$rows = [
['Param1', 'Value1'],
['Param2', 'Value2']
];
$io->table($headers, $rows); |
样式向导的API接口是精悍的、有表现力的、直观的,为的是降低学习曲线:
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 | $io = new SymfonyStyle($input, $output);
// common output elements 常规输出元素
$io->title(string $message);
$io->section(string $message);
$io->text(string|array $message);
$io->comment(string|array $message);
// more advanced output elements 高级输出元素
$io->note(string|array $message);
$io->caution(string|array $message);
$io->listing(array $elements);
$io->table(array $headers, array $rows);
// ask for user's input 要求用户输入
$io->ask(string $question, string|null $default = null, callable|null $validator = null);
$io->askHidden(string $question, callable|null $validator = null);
$io->confirm(string $question, bool $default = true);
$io->choice(string $question, array $choices, string|int|null $default = null);
// display the result of the command or some important task
// 显示当前命令或一些重要任务的执行结果
$io->success(string|array $message);
$io->error(string|array $message);
$io->warning(string|array $message); |
在实践中,上述每一种元素在命令行中的实际显示效果如下:
使用全新的样式向导之主要优点在于:
使你的命令在外观上保持一致,节省了你花在决定“哪个命令使用哪个样式”上的时间。
精简了你的命令程序中的大量代码,剔除了数百行用于决定信息表现层的代码。
你只需导入一个类(
SymfonyStyle
)即可替换掉诸多的类(Table
、ProgressBar
、ChoiceQuestion
、ConfirmationQuestion
等)。
本文在写作时,样式向导的文档还未准备好,但你可以查看内置于Symfony2.8或3.0中的源代码,它们是被整体重新设计的。