从 Symfony 5 OutputInterface 获取整个控制台输出

Get the whole console output from Symfony 5 OutputInterface

我有一个像这样的 Symfony 5 命令:

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

....

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $this->input        = $input;
        $this->output       = $output;
        $this->io           = new SymfonyStyle($input, $output);
        ....
    }

此命令生成大量输出 $this->io->caution(...)$this->io->block(....)$this->io->text(....) 等。

有时(不总是:有一些运行时条件),在执行结束时,我想访问命令生成的整个输出然后发送它通过电子邮件。那么....我怎样才能取回 OutputInterface 显示的所有内容?有没有什么$this->output->getBuffer()

我可以毫无问题地将 OutputInterface $output 换成其他东西(logger,也许吧?),只要我仍然可以在 stdoutput(我的终端)上显示我正在做的一切目前

我认为没有任何现成的工具可以为您完成此任务。你可以用记录器实现类似的东西......但是你必须 fiddle 很多配置错误级别,可能注入多个记录器,控制台输出永远不会匹配 SymfonyStyle 的输出,等等

您最好自己构建,这应该不是特别困难。只需构建 wraps/decorates SymfonyStyle 的东西;并捕获输出。

我将提供起始构建块,由您来完成实施:

class LoggingStyle
{
    private SymfonyStyle $style;
    private array        $logEntries = [];

    public function __construct(InputInterface $input, OutputInterface $output) {
        $this->style = new SymfonyStyle($input, $output);
    }

    private function addLog(string $type, string $message): void
    {
        $this->logEntries[] = [
            'type' => $type,
            'message' => $message,
            'time' => date('Y-m-d H:i:s')
        ];
    }

    public function flushLog():array
    {
        $log = $this->logEntries;
        $this->logEntries = [];

        return $log;
    }

    public function caution(string $message): void
    {
        $this->addLog('caution', $message);
        $this->style->caution($message);
    }

    public function text(string $message): void
    {
        $this->addLog('text', $message);
        $this->style->caution($message);
    }

    public function block(string $message): void
    {
        $this->addLog('block', $message);
        $this->style->caution($message);
    }
}

您需要实现您需要使用的 SymfonyStyle 界面的每个部分,并决定如何处理某些特殊行为(如果有的话)(例如 ask()table(),或进度条)。但这完全取决于您的实施。

还要决定如何设置电子邮件中每种不同输出样式的格式,因为逻辑上无法直接翻译它。

你可以直接使用这个class,如果你到达需要聚合输出的地步,你只需调用LoggingStyle::flushLog()并获取数组形式的所有条目,供你处理和相应地发送。