Skip to content

SymfonyStyle ChoiceQuestion - choice to send value or key #40439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
bastien70 opened this issue Mar 10, 2021 · 12 comments · May be fixed by #51199
Open

SymfonyStyle ChoiceQuestion - choice to send value or key #40439

bastien70 opened this issue Mar 10, 2021 · 12 comments · May be fixed by #51199

Comments

@bastien70
Copy link

Description
Currently, when creating a new Symfony command and using the choice question, like this :

return $io->choice($question, $choices, $default);

It returns the value. But I want the key ! It could be great to give the choice to send key or value with a booleen parameter, like this :

return $io->choice($question, $choices, $default, false);

Example

$choices = [
            0 => 'red',
            1 => 'blue',
            2 => 'orange'
        ];

        return $io->choice('Choose a color', $choices, 0); // Returns the value (red, blur or orange)
        return $io->choice('Choose a color', $choices, 0, false); // Returns the key (0, 1 or 2)
@alexandre-daubois
Copy link
Member

Hi!

One thing I'm wondering: are you sure it returns the value? 🤔
I just tested it out with this simple example:

public function execute(InputInterface $input, OutputInterface $output)
{
    $choices = [
        'key_0' => 'value_0',
        'key_1' => 'value_1',
        'key_2' => 'value_2',
    ];

    $io = new SymfonyStyle($input, $output);

    $value = $io->choice('Choose something', $choices);
    $output->writeln($value);

    return Command::SUCCESS;
}

And here is the output:

 Choose something:
  [key_0] value_0
  [key_1] value_1
  [key_2] value_2
 > value_1

key_1

You didn't precise which Symfony version you're using, but it seems the 5.x is doing just fine with what you're trying to accomplish: getting the key and not the value with choice method.

@ogizanagi
Copy link
Contributor

Actually, IIRC: it returns the value for lists (no keys), while it returns the key for maps.

@alexandre-daubois
Copy link
Member

Alright, thanks @ogizanagi, just tested what you said and you remembered correctly!
It brings another problem. Given that we have a different behavior between maps and lists, we can't just add something like $returnKeys (with or without default value) without breaking backward compatibility for one of these two behavior.

There might be another solution to do it? I don't know if it worth breaking backward compatibility with the proposed solution.

@carsonbot
Copy link

Thank you for this suggestion.
There has not been a lot of activity here for a while. Would you still like to see this feature?

@carsonbot
Copy link

Hello? This issue is about to be closed if nobody replies.

@carsonbot
Copy link

Hey,

I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!

@gravataLonga
Copy link

Sorry, but this is still relevant.

@apphancer
Copy link

When the keys of the choices array are integers, I get the choice result as the value of the selected choice instead of the key. The same happens when using ChoiceQuestion.

@algorun77
Copy link

algorun77 commented Jun 15, 2023

Hello, I have the same problem.

In my case, the code is:

$brands = $em->getRepository(Brand::class)->findByCompany($company);

if (count($brands) > 0) {
    $choices = [(string)0 => 'Create a new brand'];
    foreach ($brands as $brand) {
        $choices[(string)$brand->getId()] = $brand->getName();
    }
    $question = new ChoiceQuestion(
        'Which brand do you want to attach to the surveys?',
        $choices,
        0
    );
    $brandId = $this->getHelper('question')->ask($input, $output, $question);
}

But even by trying to cast the object's ID into a string, the response returned is still the name of the object and not the key of my choices array.

I also tried this

$question = new ChoiceQuestion(
    'Which brand do you want to attach to the surveys?',
    array_merge(["0" => 'Create a new brand'], $brands),
    0
);

with no luck too.

So having a way to tell the QuestionHelper if we want the key or value returned as the response would be very great as an improvement!

HOWEVER, I have to be honest, the project I'm working on is still in Symfony 2.8 (please don't judge, I've been trying for years to have it updated)

@gravataLonga
Copy link

@carsonbot open issue 👍🏼

@xabbuh xabbuh reopened this Jun 17, 2023
@stof
Copy link
Member

stof commented Jun 19, 2023

@algorun77 your casting to string is useless. PHP casts it back to integer due to the way array keys work.

@carsonbot carsonbot removed the Stalled label Jun 19, 2023
@fmarchalemisys
Copy link
Contributor

For the record, getting the key from the value is simple.

$value = $io->choice("Select a value", $choices);
$key = array_search($value, $choices);

Although I would prefer if the key was somehow returned upon request.

Honestly, I don't know what would be best: 🤔

  • One more parameter to \Symfony\Component\Console\Style\SymfonyStyle::choice.
  • A config parameter passed to ChoiceQuestion.
  • A new choiceKey function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants