clue/commander

Issue with optional arguments

Closed this issue · 4 comments

Thanks for a great package which I just discovered. I'm having a trivial issue with a simple route. Maybe you call help?

    $router->add('run [--verbose]', function (array $args) {
       ...
    });

When starting with either php index.php run --verbose or php index.php run, I always have $args[verbose] set to false. What am I doing wrong?

Hey @8ctopus, thanks for bringing this up 👍

Maybe this occurs because you're addressing your placeholder without single quotes:
$args[verbose] -> $args['verbose']

Does this fix your problem?

Hello Simon,

Unfortunately not, here's how it looks in the debugger:

2022-06-28_124807

@8ctopus You're not doing something wrong here. I checked again, it actually does what it is supposed to do ^^

As the documentation for add() says:

$router->add('user list [--json] [-f]', function (array $args) {
    assert(!isset($args['json']) || $args['json'] === false);
    assert(!isset($args['f']) || $args['f'] === false);
});
// matches: user list
// matches: user list --json
// matches: user list -f
// matches: user list -f --json
// matches: user -f list
// matches: --json user list

As seen in the example, options in the $args array can either be unset when they have not been passed in the user input or set to false when they have been passed (which is in line with how other parsers such as getopt() work).

This means your [--verbose] can have two states. When you write php index.php process --verbose it sets your $args to false and when you write php index.php process your $args is unset. You can use isset() to check if your [--verbose] got passed or not.

I hope this will answer your question.

Many thanks Simon for looking into it!

I understand it now, even if it's a bit counter-intuitive in my opinion.