Search code examples
phpsymfonysymfony-console

Symfony console - displaying help for command with no arguments


I'm developing a pretty simple Symfony console application. It has just one command with one argument, and a few options.

I followed this guide to create an extension of the Application class.

This is the normal usage for the app, and it works fine:
php application <argument>

This also works fine (argument with options):
php application.php <argument> --some-option

If someone runs php application.php without any arguments or options, I want it to run as though the user had run php application.php --help.

I do have a working solution but it isn't optimal and is perhaps slightly brittle. In my extended Application class, I overrode the run() method as follows:

/**
 * 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);
}

By default, Application::run() is called with a null InputInterface, so here I figured I could just check the raw value of the arguments and forcefully add a help option to pass to the parent method.

Is there a better way to achieve this?


Solution

  • To do a specific action depending on command, you can use an EventListener which is called when the onConsoleCommand is fired.

    The listener class should work as follows :

    <?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());
            }
        }
    }
    

    The service declaration :

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