【问题标题】:Symfony console - displaying help for command with no argumentsSymfony 控制台 - 显示不带参数的命令帮助
【发布时间】:2024-01-22 05:45:02
【问题描述】:

我正在开发一个非常简单的 Symfony 控制台应用程序。它只有一个带有一个参数的命令和几个选项。

我按照this guide 创建了Application 类的扩展。

这是该应用程序的正常用法,并且可以正常使用:
php application <argument>

这也可以正常工作(带选项的参数):
php application.php <argument> --some-option

如果有人在没有任何参数或选项的情况下运行 php application.php,我希望它像用户运行 php application.php --help 一样运行。

我确实有一个可行的解决方案,但它不是最佳的,而且可能有点脆弱。在我扩展的Application 类中,我重写了run() 方法,如下所示:

/**
 * Override parent method so that --help options is used when app is called with no arguments or options
 *
 * @param InputInterface|null $input
 * @param OutputInterface|null $output
 * @return int
 * @throws \Exception
 */
public function run(InputInterface $input = null, OutputInterface $output = null)
{
    if ($input === null) {
        if (count($_SERVER["argv"]) <= 1) {
            $args = array_merge($_SERVER["argv"], ["--help"]);
            $input = new ArgvInput($args);
        }
    }
    return parent::run($input, $output);
}

默认情况下,Application::run() 是用 null InputInterface 调用的,所以在这里我想我可以检查参数的原始值并强制添加一个帮助选项以传递给父方法。

有没有更好的方法来实现这一点?

【问题讨论】:

  • 我认为您的解决方案很好,为什么您认为它很脆弱?
  • 我不喜欢它在现有输入抽象之外工作。它也不是最易读的代码。如果您看到类似if ($this-&gt;hasNoArguments()) { $this-&gt;addOption("help", true) } 的内容,则更具可读性。

标签: php symfony symfony-console


【解决方案1】:

我设法找到了一个完全不涉及Application 类的解决方案。从另一个命令中调用帮助命令:

/**
 * @param InputInterface $input
 * @param OutputInterface $output
 * @return int
 * @throws \Symfony\Component\Console\Exception\ExceptionInterface
 */
protected function outputHelp(InputInterface $input, OutputInterface $output)
{
    $help = new HelpCommand();
    $help->setCommand($this);
    return $help->run($input, $output);
}

【讨论】:

    【解决方案2】:

    要根据命令执行特定操作,您可以使用EventListener,它会在onConsoleCommand 被触发时调用。

    监听器类应该如下工作:

    <?php
    
    namespace AppBundle\EventListener;
    
    use Symfony\Component\Console\Event\ConsoleCommandEvent;
    use Symfony\Component\Console\Command\HelpCommand;
    
    class ConsoleEventListener
    {
        public function onConsoleCommand(ConsoleCommandEvent $event)
        {
            $application = $event->getCommand()->getApplication();
            $inputDefinition = $application->getDefinition();
    
            if ($inputDefinition->getArgumentCount() < 2) {
                $help = new HelpCommand();
                $help->setCommand($event->getCommand());
    
                return $help->run($event->getInput(), $event->getOutput());
            }
        }
    }
    

    服务声明:

    services:
         # ...
         app.console_event_listener:
             class: AppBundle\EventListener\ConsoleEventListener
             tags:
                 - { name: kernel.event_listener, event: console.command, method: onConsoleCommand }
    

    【讨论】:

    • 谢谢。我认为您的答案虽然更冗长并且需要额外的课程,但可能比我自己的答案更“正确”,因为它可以更好地抽象事物。当我有机会时,我会测试它,如果它是正确的,请接受你的答案。我这周不在,所以可能需要一段时间才能到达:)
    • 不客气。我的主要目标是,如果人们有同样的需求,他可以在这里找到答案。现在我知道如何使用内置的HelpCommand。所以谢谢你的好问题