全局替代控制台样式的最干净的方法

时间:2020-07-27 15:29:18

标签: symfony console symfony4

tl; dr::我想在整个控制台应用程序中更改输出格式化程序样式,而不必修改每个命令。如何进行一组全局生效的更改?

我想全局更改my Symfony 4 Console application中的错误输出格式化程序样式。 As per the documentation,通过每个命令以临时方式进行操作很容易,例如:

public function execute(InputInterface $input, OutputInterface $output): int {
  $output->getFormatter()->setStyle('error', new OutputFormatterStyle('red'));
}

但是我不想在所有命令中添加不必要的样板,尤其是不要使用new运算符。为了可维护性和可测试性,我更喜欢通过服务容器重写并注入我的依赖项。我试图通过覆盖输出格式化程序来做到这一点:

MyOutputFormatter.php

use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

class MyOutputFormatter extends OutputFormatter {

  public function __construct($decorated = FALSE, array $styles = []) {
    // I've tried it this way:
    $styles['error'] = new OutputFormatterStyle('red');

    parent::__construct($decorated, $styles);

    // I've tried it this way:
    $this->setStyle('error', new OutputFormatterStyle('red'));

    // And I've tried it this way:
    $this->getStyle('error')->setForeground('red');
    $this->getStyle('error')->setBackground();
  }

}

services.yml:

Symfony\Component\Console\Formatter\OutputFormatterInterface:
  alias: My\Console\Formatter\OutputFormatter

MyCommand.php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class MyCommand extends Command {

  public function execute(InputInterface $input, OutputInterface $output) {
    $output->writeln("<error>I'm an error.</error>");
  }

}

但是我一定做错了,因为尽管确实可以注入和解释我的类,但是无论我尝试覆盖现有样式还是创建新样式,它都无效:我希望使用自定义样式(红色没有背景的前景),而是使用默认样式(白色前景和红色背景)。

有人可以纠正我的误解或提出更好的方法吗?谢谢!

1 个答案:

答案 0 :(得分:0)

我解决了!结果证明非常简单:Application 类有一个 configureIO() 方法正是为了这个目的。这就是我最后必须做的:

Application.php

class Application extends \Symfony\Component\Console\Application
{
    protected function configureIO(InputInterface $input, OutputInterface $output): void
    {
        $output->getFormatter()->setStyle('error', new OutputFormatterStyle('red'));
    }
}

请注意,此解决方案假定您在前端脚本中使用自己的 Application 类,例如:

bin/my-command.php

$application = new \My\Application();

$application->add(new MyCommand());
// etc.

$application->run();
相关问题