Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Console] Odd behavior with default values for multi-value options #7689

Closed
@jmikola

Description

@jmikola

For context, this came up with a console app I'm developing in mongo-cluster-tests. I'm linking to a commit hash there since I'm going to commit a work-around for this in the master branch soon after submitting this issue :)

I have the following option defined on my commands:

->addOption('readPreferenceTags', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'MongoClient read preference tags'

In practice, I would use this to pass in multiple strings to the command and access them as an array. If the option isn't used at all, the default value is an empty array.

$ ./test.php find --readPreferenceTags dc:ny --readPreferenceTags dc:sf
    -- will yield ['dc:ny', 'dc:sf'] for the option
$ ./test.php find
    -- will yield [] for the option

I discovered an edge case when the option value is missing from the command line:

$ ./test.php find --readPreferenceTags dc:ny --readPreferenceTags
    -- will yield ['dc:ny', []] for the option
$ ./test.php find --readPreferenceTags
    -- will yield [[]] for the option

Since my application expects these values to be strings, I end up with a PHP notice on the failed array-to-string conversion.

I traced this back to ArgvInput and the addLongOption() method in particular. When the incoming value is null and values are optional, the option's default value will get used (i.e. an empty array). A bit below that, when $option->isArray(), the value gets appended to the existing value array.

On a side note, if a substr() call fails and $value is false coming into addLongOption(), false will get appended to the existing value array (there's no extra array wrapping at play).

I was curious if this was simply a matter of me passing values to long options (typically taken as --option=value) as I would short options (-o value). To that end, I tested the above scenario with short options; the outcome was the same.

If this deserves a fix, I'm happy to create a PR for it. I'm sure we could add some code to addLongOption() to solve it, but I'm not certain that's the best place for it. At the very least, I will add a few test cases in the PR to cover this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions