Skip to content
  • About
    • What is Symfony?
    • Community
    • News
    • Contributing
    • Support
  • Documentation
    • Symfony Docs
    • Symfony Book
    • Screencasts
    • Symfony Bundles
    • Symfony Cloud
    • Training
  • Services
    • SensioLabs Professional services to help you with Symfony
    • Platform.sh for Symfony Best platform to deploy Symfony apps
    • SymfonyInsight Automatic quality checks for your apps
    • Symfony Certification Prove your knowledge and boost your career
    • Blackfire Profile and monitor performance of your apps
  • Other
  • Blog
  • Download
sponsored by SensioLabs
  1. Home
  2. Documentation
  3. Reference
  4. Constraints
  5. Choice
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud

Table of Contents

  • Basic Usage
  • Supplying the Choices with a Callback Function
  • Available Options
    • callback
    • choices
    • groups
    • max
    • maxMessage
    • match
    • message
    • min
    • minMessage
    • multiple
    • multipleMessage
    • payload

Choice

Edit this page

Choice

This constraint is used to ensure that the given value is one of a given set of valid choices. It can also be used to validate that each item in an array of items is one of those valid choices.

Applies to property or method
Class Choice
Validator ChoiceValidator

Basic Usage

The basic idea of this constraint is that you supply it with an array of valid values (this can be done in several ways) and it validates that the value of the given property exists in that array.

If your valid choice list is simple, you can pass them in directly via the choices option:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// src/Entity/Author.php
namespace App\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class Author
{
    const GENRES = ['fiction', 'non-fiction'];

    #[Assert\Choice(['New York', 'Berlin', 'Tokyo'])]
    protected $city;

    #[Assert\Choice(choices: Author::GENRES, message: 'Choose a valid genre.')]
    protected $genre;
}
1
2
3
4
5
6
7
8
9
# config/validator/validation.yaml
App\Entity\Author:
    properties:
        city:
            - Choice: [New York, Berlin, Tokyo]
        genre:
            - Choice:
                choices:  [fiction, non-fiction]
                message:  Choose a valid genre.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- config/validator/validation.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">

    <class name="App\Entity\Author">
        <property name="city">
            <constraint name="Choice">
                <value>New York</value>
                <value>Berlin</value>
                <value>Tokyo</value>
            </constraint>
        </property>
        <property name="genre">
            <constraint name="Choice">
                <option name="choices">
                    <value>fiction</value>
                    <value>non-fiction</value>
                </option>
                <option name="message">Choose a valid genre.</option>
            </constraint>
        </property>
    </class>
</constraint-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// src/EntityAuthor.php
namespace App\Entity;

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Mapping\ClassMetadata;

class Author
{
    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint(
            'city',
            new Assert\Choice(['New York', 'Berlin', 'Tokyo'])
        );

        $metadata->addPropertyConstraint('genre', new Assert\Choice([
            'choices' => ['fiction', 'non-fiction'],
            'message' => 'Choose a valid genre.',
        ]));
    }
}

Supplying the Choices with a Callback Function

You can also use a callback function to specify your options. This is useful if you want to keep your choices in some central location so that, for example, you can access those choices for validation or for building a select form element:

1
2
3
4
5
6
7
8
9
10
// src/Entity/Author.php
namespace App\Entity;

class Author
{
    public static function getGenres()
    {
        return ['fiction', 'non-fiction'];
    }
}

You can pass the name of this method to the callback option of the Choice constraint.

1
2
3
4
5
6
7
8
9
10
// src/Entity/Author.php
namespace App\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class Author
{
    #[Assert\Choice(callback: 'getGenres')]
    protected $genre;
}
1
2
3
4
5
# config/validator/validation.yaml
App\Entity\Author:
    properties:
        genre:
            - Choice: { callback: getGenres }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- config/validator/validation.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">

    <class name="App\Entity\Author">
        <property name="genre">
            <constraint name="Choice">
                <option name="callback">getGenres</option>
            </constraint>
        </property>
    </class>
</constraint-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/EntityAuthor.php
namespace App\Entity;

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Mapping\ClassMetadata;

class Author
{
    protected $genre;

    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('genre', new Assert\Choice([
            'callback' => 'getGenres',
        ]));
    }
}

If the callback is defined in a different class and is static, for example App\Entity\Genre, you can pass the class name and the method as an array.

1
2
3
4
5
6
7
8
9
10
11
// src/Entity/Author.php
namespace App\Entity;

use App\Entity\Genre
use Symfony\Component\Validator\Constraints as Assert;

class Author
{
    #[Assert\Choice(callback: [Genre::class, 'getGenres'])]
    protected $genre;
}
1
2
3
4
5
# config/validator/validation.yaml
App\Entity\Author:
    properties:
        genre:
            - Choice: { callback: [App\Entity\Genre, getGenres] }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- config/validator/validation.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">

    <class name="App\Entity\Author">
        <property name="genre">
            <constraint name="Choice">
                <option name="callback">
                    <value>App\Entity\Genre</value>
                    <value>getGenres</value>
                </option>
            </constraint>
        </property>
    </class>
</constraint-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// src/Entity/Author.php
namespace App\Entity;

use App\Entity\Genre;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Mapping\ClassMetadata;

class Author
{
    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('genre', new Assert\Choice([
            'callback' => [Genre::class, 'getGenres'],
        ]));
    }
}

Available Options

callback

type: string|array|Closure

This is a callback method that can be used instead of the choices option to return the choices array. See Supplying the Choices with a Callback Function for details on its usage.

choices

type: array [default option]

A required option (unless callback is specified) - this is the array of options that should be considered in the valid set. The input value will be matched against this array.

groups

type: array | string default: null

It defines the validation group or groups of this constraint. Read more about validation groups.

max

type: integer

If the multiple option is true, then you can use the max option to force no more than XX number of values to be selected. For example, if max is 3, but the input array contains 4 valid items, the validation will fail.

maxMessage

type: string default: You must select at most {{ limit }} choices.

This is the validation error message that's displayed when the user chooses too many options per the max option.

You can use the following parameters in this message:

Parameter Description
{{ choices }} A comma-separated list of available choices
{{ value }} The current (invalid) value

match

type: boolean default: true

When this option is false, the constraint checks that the given value is not one of the values defined in the choices option. In practice, it makes the Choice constraint behave like a NotChoice constraint.

6.2

The match option was introduced in Symfony 6.2.

message

type: string default: The value you selected is not a valid choice.

This is the message that you will receive if the multiple option is set to false and the underlying value is not in the valid array of choices.

You can use the following parameters in this message:

Parameter Description
{{ choices }} A comma-separated list of available choices
{{ value }} The current (invalid) value

min

type: integer

If the multiple option is true, then you can use the min option to force at least XX number of values to be selected. For example, if min is 3, but the input array only contains 2 valid items, the validation will fail.

minMessage

type: string default: You must select at least {{ limit }} choices.

This is the validation error message that's displayed when the user chooses too few choices per the min option.

You can use the following parameters in this message:

Parameter Description
{{ choices }} A comma-separated list of available choices
{{ value }} The current (invalid) value

multiple

type: boolean default: false

If this option is true, the input value is expected to be an array instead of a single, scalar value. The constraint will check that each value of the input array can be found in the array of valid choices. If even one of the input values cannot be found, the validation will fail.

multipleMessage

type: string default: One or more of the given values is invalid.

This is the message that you will receive if the multiple option is set to true and one of the values on the underlying array being checked is not in the array of valid choices.

You can use the following parameters in this message:

Parameter Description
{{ value }} The current (invalid) value
{{ label }} Corresponding form field label

payload

type: mixed default: null

This option can be used to attach arbitrary domain-specific data to a constraint. The configured payload is not used by the Validator component, but its processing is completely up to you.

For example, you may want to use several error levels to present failed constraints differently in the front-end depending on the severity of the error.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version
    We stand with Ukraine.
    Version:

    Symfony 6.2 is backed by

    Symfony 6.2 is backed by

    Online exam, become Sylius certified today

    Online exam, become Sylius certified today

    Code consumes server resources. Blackfire tells you how

    Code consumes server resources. Blackfire tells you how

    Symfony footer

    ↓ Our footer now uses the colors of the Ukrainian flag because Symfony stands with the people of Ukraine.

    Avatar of Ivan Gantsev, a Symfony contributor

    Thanks Ivan Gantsev for being a Symfony contributor

    1 commit • 6 lines changed

    View all contributors that help us make Symfony

    Become a Symfony contributor

    Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

    Learn how to contribute

    Symfony™ is a trademark of Symfony SAS. All rights reserved.

    • What is Symfony?

      • Symfony at a Glance
      • Symfony Components
      • Case Studies
      • Symfony Releases
      • Security Policy
      • Logo & Screenshots
      • Trademark & Licenses
      • symfony1 Legacy
    • Learn Symfony

      • Symfony Docs
      • Symfony Book
      • Reference
      • Bundles
      • Best Practices
      • Training
      • eLearning Platform
      • Certification
    • Screencasts

      • Learn Symfony
      • Learn PHP
      • Learn JavaScript
      • Learn Drupal
      • Learn RESTful APIs
    • Community

      • SymfonyConnect
      • Support
      • How to be Involved
      • Code of Conduct
      • Events & Meetups
      • Projects using Symfony
      • Downloads Stats
      • Contributors
      • Backers
    • Blog

      • Events & Meetups
      • A week of symfony
      • Case studies
      • Cloud
      • Community
      • Conferences
      • Diversity
      • Documentation
      • Living on the edge
      • Releases
      • Security Advisories
      • SymfonyInsight
      • Twig
      • SensioLabs
    • Services

      • SensioLabs services
      • Train developers
      • Manage your project quality
      • Improve your project performance
      • Host Symfony projects

      Deployed on

    Follow Symfony

    Search by Algolia