15

With the Symfony3 Console, how can I tell when a user supplied an option, but supplied it without a value? As opposed to not supplying the option at all?

As an example, take the following console configuration.

<?php

class MyCommand extends \Symfony\Component\Console\Command\Command
{
    // ...

    protected function configure()
    {
        $this->setName('test')
            ->setDescription('update an existing operation.')
            ->addOption(
                'option',
                null,
                InputOption::VALUE_OPTIONAL,
                'The ID of the operation to update.'
            );
    }
}

The command help will illustrate the option as --option[=OPTION], so I can call this the following ways.

bin/console test
bin/console test --option
bin/console test --option=foo

However, $input->getOption() will return NULL in the first two cases. I expected in the second case that it would return TRUE, or something to indicate the option was supplied.

So I don't know how to identify the difference the option not being supplied at all, and it being supplied but without a value.

If there is no way to tell the difference, what is the use-case for InputOption::VALUE_OPTIONAL?

Courtney Miles
  • 3,756
  • 3
  • 29
  • 47

4 Answers4

14

Since Symfony 3.4, you can just set the default to false and check:

  1. if the value is false the option doesn't exist
  2. if the value is null the option exists without a value
  3. otherwise it has its value

e.g.

$this->addOption('force', null, InputOption::VALUE_OPTIONAL, 'Force something', false);

$force = $input->getOption('force') !== false;
miken32
  • 42,008
  • 16
  • 111
  • 154
ScorpioT1000
  • 319
  • 2
  • 7
8

You're combining two things together. Option with no value InputOption::VALUE_NONE and an option with an optional value InputOption::VALUE_OPTIONAL.

The documentation says: http://symfony.com/doc/current/console/input.html

There is nothing forbidding you to create a command with an option that optionally accepts a value. However, there is no way you can distinguish when the option was used without a value (command --language) or when it wasn't used at all (command). In both cases, the value retrieved for the option will be null.

This describes exactly your case.

You can't distinguish when a parameter wasn't passed at all or was passed but with no value. That's what InputOption::VALUE_NONE was made for.

Depending on your usecase you can supply a default value for a parameter which will be used in console test and console test --option cases.

Also note, that addOption takes as an argument a shortcut as the second argument.

public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
martin
  • 93,354
  • 25
  • 191
  • 226
  • 1
    Thanks for confirming. It still raises the question (not at you, but just in general,) why does this feature exists? I.e. Why offer the the ability for an option to have an optional value if the command can only identify the option was provided when it has a value. How does someone put that to good use? – Courtney Miles Sep 09 '16 at 11:12
  • Simple - switches! `command` would simply run it, `command --verbose` would run it verbose. – Rob Mar 01 '19 at 20:12
  • `$input->getOption('switch-option')` should either return `true` or `false` based on its existence. – ssi-anik Sep 29 '22 at 03:17
8

Edit on 6/10/21: This only applies to Symfony 3.3 and below. The correct answer is now the one provided by ScorpioT1000

After poking around in Symfony\Component\Console\Input\InputInterface, I discovered the getParameterOption() method which provides the ability to differentiate between an option not used, an option used without a value, and an option used with a value.

In the command's configure() method:

$this->addOption('test', null, InputOption::VALUE_OPTIONAL);

In the command's execute() method:

$test = $input->getOption('test'); $rawTest = $input->getParameterOption('--test');

Produces the following values for the given command lines:

> bin/console some:cmd

$test => null

$rawTest => false

> bin/console some:cmd --test

$test => null

$rawTest => null

> bin/console some:cmd --test=something

$test => "something"

$rawTest => "something"

JasonGabler
  • 570
  • 5
  • 9
0

For some reason, the other answers didn't work for me. What worked for me was:

if (is_null($input->getParameterOption('--zip', 'NOT_SET'))) {
  // --zip without a value.
}
Lucas Bustamante
  • 15,821
  • 7
  • 92
  • 86