Ein eigener Validator
Ein eigener Validator
~16 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Die eingebauten Constraints reichen nicht IMMER aus – ein EIGENER Validator prüft hier, ob der name eines Projekts BEREITS existiert.
Die Constraint-Klasse anlegen
docker compose exec php bin/console make:validator UniqueProjectName<?php
declare(strict_types=1);
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
#[\Attribute]
final class UniqueProjectName extends Constraint
{
public string $message = 'Ein Projekt mit dem Namen "{{ value }}" existiert bereits.';
}Den Validator implementieren
<?php
declare(strict_types=1);
namespace App\Validator;
use App\Repository\ProjectRepository;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
final class UniqueProjectNameValidator extends ConstraintValidator
{
public function __construct(
private readonly ProjectRepository $projectRepository,
) {
}
public function validate(mixed $value, Constraint $constraint): void
{
if (!$constraint instanceof UniqueProjectName) {
return;
}
if (null === $value || '' === $value) {
return;
}
$existing = $this->projectRepository->findOneBy(['name' => $value]);
if (null !== $existing) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $value)
->addViolation();
}
}
}GENAU dasselbe Constraint/ConstraintValidator-Paar-Prinzip wie in der Symfony-Schulung (Kapitel 26) – Dependency Injection funktioniert im Validator NORMAL, ProjectRepository wird AUTOMATISCH injiziert.
Den Validator anwenden
use App\Validator\UniqueProjectName;
#[ORM\Column(length: 255)]
#[Assert\NotBlank]
#[UniqueProjectName]
#[Groups(['project:read', 'project:write'])]
private string $name = '';Das Verhalten testen
curl -k -X POST https://localhost/api/projects \
-H 'Content-Type: application/json' \
-d '{"name": "Website-Relaunch"}'{
"violations": [
{"propertyPath": "name", "message": "Ein Projekt mit dem Namen \"Website-Relaunch\" existiert bereits."}
]
}Tipp: Symfony bietet AUCH eine fertige #[UniqueEntity]-Constraint für GENAU diesen Fall – dieses Kapitel zeigt bewusst den MANUELLEN Weg, da er zeigt, WIE beliebige EIGENE Geschäftsregeln (nicht nur Eindeutigkeit) als Validator umgesetzt werden können.