Cover of the book Symfony 5: The Fast Track

Symfony 5: The Fast Track is the best book to learn modern Symfony development, from zero to production. +300 pages showcasing Symfony with Docker, APIs, queues & async tasks, Webpack, SPAs, etc.

New in Symfony 4.3: Automatic validation

Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.

Contributed by
Kévin Dunglas
in #27735.

Consider the following simple Doctrine entity:

use Doctrine\ORM\Mapping as ORM;

/** @ORM\Entity */
class SomeEntity
    // ...

    /** @ORM\Column(length=4) */
    public $pinCode;

Will the following code result in a validation error?

$entity = new SomeEntity();
$entity->pinCode = '1234567890';
$violationList = $validator->validate($entity);

The answer is ... no. Surprisingly, many Symfony developers still don't realize that the Doctrine mapping configuration (e.g. @ORM\Column(length=4)) doesn't actually validate anything. This config is just a hint for the Doctrine schema generator. This can lead to usability and even security issues.

In Symfony 4.3 we improved this by introducing automatic validation based on Doctrine mapping. That's why in Symfony 4.3, the previous example would have produced the following result:

$violationList = $validator->validate($entity);

var_dump((string) $violationList);
// Object(App\Entity\SomeEntity).columnLength:\n
//     This value is too long. It should have 4 characters or less.
//     (code d94b19cc-114f-4f44-9cc4-4138e80a87b9)\n

This new feature introspects mappings like @ORM\Column(length=4) to add the related @Assert\Length(max=4) validation automatically to that same property. Specifically, the following validations are automated:

Doctrine mapping Automatic validation constraint
nullable=false @Assert\NotNull
type=... @Assert\Type(...)
unique=true @UniqueEntity
length=... @Assert\Length(...)

The automatic validation of nullable=false and type=... requires to have the PropertyInfo component installed. Also, this new feature will be disabled by default, but enabled for new projects.

Since the Form component as well as API Platform internally use the Validator component, all your forms and web APIs will also automatically benefit from these automatic constraints.

Lastly, keep in mind that, although this automatic validation is convenient, it's not enough for most applications, so you will still need to manually configure more Symfony validation constraints.

Help the Symfony project!

As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.


Nice job !
Seems to be a nice new feature :)

As it will be opt-in (so disabled by default for existing Sf apps) could you add the required configuration for existing apps? Thanks :)
I guess the validation constraint for the doctrine mapping of nullable=false should be Assert\NotNull rather than for doctrine mapping of nullable=true ?
@Oliver yes! that was a mistake and it's now fixed.

@Jonathan the code to make this configurable in DoctrineBundle is still pending. I'll update the post when it's merged. Thanks.
Very clever, nice job
Symfony 4.3 is going to be really awesome! 🎉
Love it!
Very nice addition, thanks!
length doesn‘t actually validate anything?

Oh boy, I have to overthink my whole application
It would be nice to mention in the post how exactly to enable/disable this feature
@Tito the option to enable/disable this feature is not ready yet. See We'll update the blog post when this is ready.
Awesome feature! Nice job, thanks
Nice job ! The minimum validation requirements are now free ! Thanks.
Nice and useful update ! Can't wait to put hands on Symfony 4.3 :D
Looks nice for the common case.

But ... how does this handle custom field types that extend basic field types? Not that I would do this, but assuming I would extend an int type to store the year of something and the phpvalue would be a DateTime. Or I have some Object (in php) that is mapped to some string with known max length (in db)? I could have a length attribute in the definition, but the value might be an object. Are lifecycle handlers run before/after validation? Can this "magic" validation be enabled/disabled globally only? What if the db field is not nullable (-> NotBlank?) but the mapper of the custom type will ensure that it is not null? or the lifecycle handler does ensure this?

I see so many edge cases with this ... and have the feeling it would be better to explicitly state that doctrine annotations are not validation constraints (which seems somewhat obvious...).
Agree every point with Jochen Taeschner. I did this feature time ago for Symfony 3, but I have to roll it back because I faced many issues, including those Jochen said above. Finally, I decided to create a validator command to check for Doctrine metadata on entity fields and to check if it has the corresponding validation constraints or not, so I can avoid that problem when necessary, and I can annotate when not necessary (and why). Appart from what Jochen said, I faced those problems:

- Multi-step forms: when not all fields are shown in the form. Example: when the fields in the next step won't be visible, and if they are required... will it throw a validation error because the entity has a nullable=false field with no value?
- What about validation groups? Is it going to affect only to Default, or any validation group?
- Also about nullable=false with Assert\NotNull. As Jochen said, I had to switch to use NotBlank. Now it looks like this feature will use Assert\NotNull. Are you going to change NotNull behavior to not allow empty strings, or is Doctrine going to store null in the database when empty strings are received?
This is great. Even for us who knew that Validation should be added separately, it was still easy to forget and a general pain in the ass. Thanks so much for doing this automatically :) Makes our lives easier and our apps more consistent
This is good for Symfony developers that unaware of validations.

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.