New in Symfony 5.4: Nested Validation Attributes

Contributed by
Alexandre Daubois
in #41994.

In Symfony 5.2 we added a feature to define validation constraints as PHP attributes.
Attributes were very recent at that time, because they had just been added to
PHP 8.0. The only caveat was that you couldn’t nest PHP attributes, so you
couldn’t use them with constraints such as AtLeastOneOf and Collection.

Thankfully, PHP 8.1, released on November 25, 2021, adds support for nested
attributes. That’s why in Symfony 5.4 you’ll be able to use PHP attributes to
define all existing constraints, without any exemption.

The trick that enables this feature is to use the new keyword to create the
nested attribute:

1
2
3
4
5
6
7
#[Attribute1(new SubAttribute1())]
#[Attribute2([new SubAttribute2(), new SubAttribute3()])]
#[Attribute3(someProperty: new SubAttribute4())]
class SomeClass
{
// …
}

This is how it looks in practice when using Symfony Validator constraints in a
complex example:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
use SymfonyComponentValidatorConstraints as Assert;

class SomeClass
{
#[AssertAll([
new AssertNotNull(),
new AssertRange(min: 3),
])]
#[AssertCollection(
fields: [
‚foo‘ => [
new AssertNotNull(),
new AssertRange(min: 3),
],
‚bar‘ => new AssertRange(min: 5),
‚baz‘ => new AssertRequired([new AssertEmail()]),
‚qux‘ => new AssertOptional([new AssertNotBlank()]),
],
allowExtraFields: true
)]
private $property1;

#[AssertAtLeastOneOf(
constraints: [
new AssertNotNull(),
new AssertRange(min: 3),
],
message: ‚foo‘,
includeInternalMessages: false,
)]
#[AssertSequentially([
new AssertNotBlank(),
new AssertRange(min: 5),
])]
private $property2;

// …
}

Sponsor the Symfony project.

Symfony Blog
Read More

Latest News

PHP-Releases

PHP 8.0.19 released!

PHP 7.4.29 released!