Symfony
sponsored by SensioLabs
Menu
  • About
  • Documentation
  • Screencasts
  • Cloud
  • Certification
  • Community
  • Businesses
  • News
  • Download
  1. Home
  2. Documentation
  3. Reference
  4. Constraints
  5. Callback
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud
Search by Algolia

Table of Contents

  • Setup
  • The Callback Method
  • Options
    • methods

Callback

Edit this page

Warning: You are browsing the documentation for Symfony 2.2, which is no longer maintained.

Read the updated version of this page for Symfony 6.2 (the current stable version).

Callback

The purpose of the Callback assertion is to let you create completely custom validation rules and to assign any validation errors to specific fields on your object. If you're using validation with forms, this means that you can make these custom errors display next to a specific field, instead of simply at the top of your form.

This process works by specifying one or more callback methods, each of which will be called during the validation process. Each of those methods can do anything, including creating and assigning validation errors.

Note

A callback method itself doesn't fail or return any value. Instead, as you'll see in the example, a callback method has the ability to directly add validator "violations".

Applies to class
Options
  • methods
Class Callback
Validator CallbackValidator

Setup

  • YAML
  • Annotations
  • XML
  • PHP
1
2
3
4
5
# src/Acme/BlogBundle/Resources/config/validation.yml
Acme\BlogBundle\Entity\Author:
    constraints:
        - Callback:
            methods:   [isAuthorValid]
1
2
3
4
5
6
7
8
9
10
11
// src/Acme/BlogBundle/Entity/Author.php
namespace Acme\BlogBundle\Entity;

use Symfony\Component\Validator\Constraints as Assert;

/**
 * @Assert\Callback(methods={"isAuthorValid"})
 */
class Author
{
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- src/Acme/BlogBundle/Resources/config/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 http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">

    <class name="Acme\BlogBundle\Entity\Author">
        <constraint name="Callback">
            <option name="methods">
                <value>isAuthorValid</value>
            </option>
        </constraint>
    </class>
</constraint-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// src/Acme/BlogBundle/Entity/Author.php
namespace Acme\BlogBundle\Entity;

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

class Author
{
    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addConstraint(new Assert\Callback(array(
            'methods' => array('isAuthorValid'),
        )));
    }
}

The Callback Method

The callback method is passed a special ExecutionContextInterface object. You can set "violations" directly on this object and determine to which field those errors should be attributed:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// ...
use Symfony\Component\Validator\ExecutionContextInterface;

class Author
{
    // ...
    private $firstName;

    public function isAuthorValid(ExecutionContextInterface $context)
    {
        // somehow you have an array of "fake names"
        $fakeNames = array();
    
        // check if the name is actually a fake name
        if (in_array($this->getFirstName(), $fakeNames)) {
            $context->addViolationAt('firstname', 'This name sounds totally fake!', array(), null);
        }
    }
}

Options

methods

type: array default: array() [default option]

This is an array of the methods that should be executed during the validation process. Each method can be one of the following formats:

  1. String method name

    If the name of a method is a simple string (e.g. isAuthorValid), that method will be called on the same object that's being validated and the ExecutionContextInterface will be the only argument (see the above example).

  2. Static array callback

    Each method can also be specified as a standard array callback:

    • YAML
    • Annotations
    • XML
    • PHP
    1
    2
    3
    4
    5
    6
    # src/Acme/BlogBundle/Resources/config/validation.yml
    Acme\BlogBundle\Entity\Author:
        constraints:
            - Callback:
                methods:
                    -    [Acme\BlogBundle\MyStaticValidatorClass, isAuthorValid]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // src/Acme/BlogBundle/Entity/Author.php
    use Symfony\Component\Validator\Constraints as Assert;
    
    /**
     * @Assert\Callback(methods={
     *     { "Acme\BlogBundle\MyStaticValidatorClass", "isAuthorValid"}
     * })
     */
    class Author
    {
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <!-- src/Acme/BlogBundle/Resources/config/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 http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
    
        <class name="Acme\BlogBundle\Entity\Author">
            <constraint name="Callback">
                <option name="methods">
                    <value>
                        <value>Acme\BlogBundle\MyStaticValidatorClass</value>
                        <value>isAuthorValid</value>
                    </value>
                </option>
            </constraint>
        </class>
    </constraint-mapping>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // src/Acme/BlogBundle/Entity/Author.php
    
    use Symfony\Component\Validator\Mapping\ClassMetadata;
    use Symfony\Component\Validator\Constraints\Callback;
    
    class Author
    {
        public $name;
    
        public static function loadValidatorMetadata(ClassMetadata $metadata)
        {
            $metadata->addConstraint(new Callback(array(
                'methods' => array(
                    array('Acme\BlogBundle\MyStaticValidatorClass', 'isAuthorValid'),
                ),
            )));
        }
    }

    In this case, the static method isAuthorValid will be called on the Acme\BlogBundle\MyStaticValidatorClass class. It's passed both the original object being validated (e.g. Author) as well as the ExecutionContextInterface:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    namespace Acme\BlogBundle;
    
    use Symfony\Component\Validator\ExecutionContextInterface;
    use Acme\BlogBundle\Entity\Author;
    
    class MyStaticValidatorClass
    {
        public static function isAuthorValid(Author $author, ExecutionContextInterface $context)
        {
            // ...
        }
    }

    Tip

    If you specify your Callback constraint via PHP, then you also have the option to make your callback either a PHP closure or a non-static callback. It is not currently possible, however, to specify a service as a constraint. To validate using a service, you should create a custom validation constraint and add that new constraint to your class.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
We stand with Ukraine.
Version:
Check Code Performance in Dev, Test, Staging & Production

Check Code Performance in Dev, Test, Staging & Production

Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).

Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).

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

Avatar of Iulian Popa, a Symfony contributor

Thanks Iulian Popa (@iulyanp) for being a Symfony contributor

3 commits • 40 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