In some Symfony applications, it is common to use the same set of constraints in different places. This tutorial explains how to create a reusable set of constraints in Symfony 7 application.
Symfony provides the Compound
constraint that defines an abstract getConstraints
method. A class that extends Compound
constraint should implement the getConstraints
method and return a set of constraints.
<?php
namespace App\Validator\Constraints;
use Attribute;
use Symfony\Component\Validator\Constraints\Compound;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
#[Attribute]
class UsernameRequirements extends Compound
{
protected function getConstraints(array $options): array
{
return [
new NotBlank(),
new Length(['min' => 5]),
];
}
}
Now custom constraint can be used as usual and reused in many places.
<?php
namespace App\Entity;
use App\Validator\Constraints as AppAssert;
class User
{
#[AppAssert\UsernameRequirements]
private string $username;
public function getUsername(): string { return $this->username; }
public function setUsername(string $username): void { $this->username = $username; }
}
For testing purpose, in the controller we created an instance of the User
class and set a short username. We validate the instance and return a response with errors.
<?php
namespace App\Controller;
use App\Entity\User;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class TestController
{
#[Route('/')]
public function index(ValidatorInterface $validator): Response
{
$user = new User();
$user->setUsername('foo');
$errors = $validator->validate($user);
if (count($errors) > 0) {
return new Response((string) $errors); // Output: value is too short
}
return new Response('Valid');
}
}
Leave a Comment
Cancel reply