Skip to content

Commit a05b002

Browse files
Jean85javiereguiluz
authored andcommitted
Add 2 solutions for the 'option with optional argument' problem
1 parent 63359a5 commit a05b002

File tree

1 file changed

+68
-15
lines changed

1 file changed

+68
-15
lines changed

console/input.rst

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,15 @@ values after a white space or an ``=`` sign (e.g. ``--iterations 5`` or
179179
``--iterations=5``), but short options can only use white spaces or no
180180
separation at all (e.g. ``-i 5`` or ``-i5``).
181181

182+
.. caution::
183+
184+
While it is possible to separate an option from its value with a white space,
185+
using this form leads to an ambiguity should the option appear before the
186+
command name. For example, ``php app/console --iterations 5 app:greet Fabien``
187+
is ambiguous; Symfony would interpret ``5`` as the command name. To avoid
188+
this situation, always place options after the command name, or avoid using
189+
a space to separate the option name from its value.
190+
182191
There are four option variants you can use:
183192

184193
``InputOption::VALUE_IS_ARRAY``
@@ -209,25 +218,69 @@ You can combine ``VALUE_IS_ARRAY`` with ``VALUE_REQUIRED`` or
209218
array('blue', 'red')
210219
);
211220

212-
.. tip::
221+
Options with optional arguments
222+
-------------------------------
213223

214-
There is nothing forbidding you to create a command with an option that
215-
optionally accepts a value. However, there is no way you can distinguish
216-
when the option was used without a value (``command --language``) or when
217-
it wasn't used at all (``command``). In both cases, the value retrieved for
218-
the option will be ``null``.
224+
There is nothing forbidding you to create a command with an option that
225+
optionally accepts a value, but it's a bit tricky. Let's use this
226+
option definition as an example::
219227

220-
Similarly, due to a PHP limitation, there is no way to pass an empty string
221-
as the value of an option. In ``command --prefix`` and ``command --prefix=''``
222-
cases, the value of the ``prefix`` option will be ``null``.
228+
// ...
229+
use Symfony\Component\Console\Input\InputOption;
230+
231+
$this
232+
// ...
233+
->addOption(
234+
'yell',
235+
null,
236+
InputOption::VALUE_OPTIONAL,
237+
'Should I yell while greeting?'
238+
);
239+
240+
We want to use this option in 3 ways: ``--yell``, ``yell=louder``, and not
241+
passing the option at all; however, the task of distinguishing between when
242+
the option was used without a value (``greet --yell``) or when it wasn't used
243+
at all (``greet``) it's a bit impervious.
244+
245+
To solve this issue, you have two possible solutions: in the first case, you
246+
can use the ``hasParameterOption`` method::
247+
248+
if ($input->hasParameterOption('--yell')) {
249+
$yell = true;
250+
$yellLouder = $input->getOption('yell') === 'louder';
251+
}
223252

224253
.. caution::
225254

226-
While it is possible to separate an option from its value with a white space,
227-
using this form leads to an ambiguity should the option appear before the
228-
command name. For example, ``php app/console --iterations 5 app:greet Fabien``
229-
is ambiguous; Symfony would interpret ``5`` as the command name. To avoid
230-
this situation, always place options after the command name, or avoid using
231-
a space to separate the option name from its value.
255+
Note that the ``hasParameterOption`` method requires prepending ``--``
256+
to the option name.
257+
258+
The second solution is to alter the option definition, setting the default value
259+
to ``false``::
260+
261+
// ...
262+
use Symfony\Component\Console\Input\InputOption;
263+
264+
$this
265+
// ...
266+
->addOption(
267+
'yell',
268+
null,
269+
InputOption::VALUE_OPTIONAL,
270+
'Should I yell while greeting?',
271+
false // this is the new default value, instead of null
272+
);
273+
274+
And then checking carefully the value of the option, minding that ``false !== null``::
275+
276+
$optionValue = $input->getOptions('yell');
277+
$yell = ($optionValue !== false);
278+
$yellLouder = ($optionValue === 'louder');
279+
280+
.. caution::
281+
282+
Due to a PHP limitation, passing an empty string is indistinguishable from
283+
not passing any value at all. In ``command --prefix`` and ``command --prefix=''``
284+
cases, the value of the ``prefix`` option will be ``null``.
232285

233286
.. _`docopt standard`: http://docopt.org/

0 commit comments

Comments
 (0)