【问题标题】:Why is it bad to make $output a Symfony command class property为什么将 $output 设置为 Symfony 命令类属性不好
【发布时间】:2018-04-08 03:26:25
【问题描述】:

我将编写一些命令来检查我的应用程序是否一切正常。

因为这些命令将由 cronjob 执行,所以我想将输出格式化为可在日志文件中利用。

为了在命令中的任何位置显示错误消息(在每个方法调用中不传递 $output),我将其设为类属性,它非常方便但看起来很糟糕,我知道它很糟糕但我不知道为什么。这是一个例子:

<?php
namespace CheckingBundle\Command;

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

/**
 * Class CheckingCommand
 *
 */
class CheckingCommand extends Command
{
    /**
     * @var OutputInterface $output
     */
    private $output;

    protected function configure()
    {
        $this->setName('check:all');
    }

    protected function initialize(InputInterface $input, OutputInterface $output)
    {
        $this->output = $output;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->checkSqlConnection();
    }

    protected function checkSqlConnection()
    {
        $myConnexion = null; //Try to connect to database
        if (null === $myConnexion) {
            $this->sendError('Cannot connect to MySQL database');
        }
    }

    /**
     * @param string $errorMessage
     */
    protected function sendError($errorMessage)
    {
        $this->output->write(sprintf('%s <error>%s</error>', date('Y-m-d H:i:s'), $errorMessage));
    }
}

有人能解释一下它为什么不好(如果是的话)吗?最好到处传递它:

 $this->checkSqlConnection($output);

 protected function checkSqlConnection(Output $output)
   {
       $myConnexion = null; //Try to connect to database
       if (null === $myConnexion) {
           $output->write('Cannot connect to MySQL database');
       }
   }

我应该在我的命令中使用 Exceptions 和 try/catch 并在 catch 中使用我的 sendError 方法吗?这可能是处理错误的好方法,但如果我想在方法中显示其他信息怎么办?

【问题讨论】:

  • 这是相当主观的,但我猜它是“坏的”,因为格式化输出不是 command 类的责任。你应该有一个OutputFormatter 或其他东西来处理这个责任。

标签: php symfony console command


【解决方案1】:

有两点我想指出, 1)checkSqlConnection不应该在命令类中,它应该在一个单独的类中(可能是一个服务),你需要将这个类作为服务公开并从命令类中使用它,你的业务逻辑不应该在命令类

2) 正如您所提到的,传递 $input$output 实例并不是好的代码,这不好,因为您的服务类将与输入/输出类紧密耦合

解决方案?使用 Monolog 代替 outputInterface, 从 symfony 2.4 开始,控制台组件与 Monolog 集成,它具有控制台处理程序,用于侦听控制台事件并根据日志级别和控制台详细程度将日志消息写入控制台输出

Read more

【讨论】:

    猜你喜欢
    • 2011-07-24
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多