The ValidatorServiceProvider provides a service for validating data. It is most useful when used with the FormServiceProvider, but can also be used standalone.
validator: An instance of Validator.
validator.mapping.class_metadata_factory: Factory for metadata loaders, which can read validation constraint information from classes. Defaults to StaticMethodLoader--ClassMetadataFactory.
This means you can define a static loadValidatorMetadata
method on your
data class, which takes a ClassMetadata argument. Then you can set
constraints on this ClassMetadata instance.
1 | $app->register(new Silex\Provider\ValidatorServiceProvider());
|
Note
The Symfony Validator Component comes with the "fat" Silex archive but not with the regular one. If you are using Composer, add it as a dependency:
1 | composer require symfony/validator
|
The Validator provider provides a validator
service.
You can validate values directly using the validate
validator
method:
1 2 3 4 5 6 7 8 9 10 11 | use Symfony\Component\Validator\Constraints as Assert;
$app->get('/validate/{email}', function ($email) use ($app) {
$errors = $app['validator']->validate($email, new Assert\Email());
if (count($errors) > 0) {
return (string) $errors;
} else {
return 'The email is valid';
}
});
|
Validating associative arrays is like validating simple values, with a collection of constraints:
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 Symfony\Component\Validator\Constraints as Assert;
class Book
{
public $title;
public $author;
}
class Author
{
public $first_name;
public $last_name;
}
$book = array(
'title' => 'My Book',
'author' => array(
'first_name' => 'Fabien',
'last_name' => 'Potencier',
),
);
$constraint = new Assert\Collection(array(
'title' => new Assert\Length(array('min' => 10)),
'author' => new Assert\Collection(array(
'first_name' => array(new Assert\NotBlank(), new Assert\Length(array('min' => 10))),
'last_name' => new Assert\Length(array('min' => 10)),
)),
));
$errors = $app['validator']->validate($book, $constraint);
if (count($errors) > 0) {
foreach ($errors as $error) {
echo $error->getPropertyPath().' '.$error->getMessage()."\n";
}
} else {
echo 'The book is valid';
}
|
If you want to add validations to a class, you can define the constraint for
the class properties and getters, and then call the validate
method:
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 | use Symfony\Component\Validator\Constraints as Assert;
$author = new Author();
$author->first_name = 'Fabien';
$author->last_name = 'Potencier';
$book = new Book();
$book->title = 'My Book';
$book->author = $author;
$metadata = $app['validator.mapping.class_metadata_factory']->getMetadataFor('Author');
$metadata->addPropertyConstraint('first_name', new Assert\NotBlank());
$metadata->addPropertyConstraint('first_name', new Assert\Length(array('min' => 10)));
$metadata->addPropertyConstraint('last_name', new Assert\Length(array('min' => 10)));
$metadata = $app['validator.mapping.class_metadata_factory']->getMetadataFor('Book');
$metadata->addPropertyConstraint('title', new Assert\Length(array('min' => 10)));
$metadata->addPropertyConstraint('author', new Assert\Valid());
$errors = $app['validator']->validate($book);
if (count($errors) > 0) {
foreach ($errors as $error) {
echo $error->getPropertyPath().' '.$error->getMessage()."\n";
}
} else {
echo 'The author is valid';
}
|
You can also declare the class constraint by adding a static
loadValidatorMetadata
method to your classes:
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 39 40 41 42 43 44 45 46 47 | use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints as Assert;
class Book
{
public $title;
public $author;
static public function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata->addPropertyConstraint('title', new Assert\Length(array('min' => 10)));
$metadata->addPropertyConstraint('author', new Assert\Valid());
}
}
class Author
{
public $first_name;
public $last_name;
static public function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata->addPropertyConstraint('first_name', new Assert\NotBlank());
$metadata->addPropertyConstraint('first_name', new Assert\Length(array('min' => 10)));
$metadata->addPropertyConstraint('last_name', new Assert\Length(array('min' => 10)));
}
}
$app->get('/validate/{email}', function ($email) use ($app) {
$author = new Author();
$author->first_name = 'Fabien';
$author->last_name = 'Potencier';
$book = new Book();
$book->title = 'My Book';
$book->author = $author;
$errors = $app['validator']->validate($book);
if (count($errors) > 0) {
foreach ($errors as $error) {
echo $error->getPropertyPath().' '.$error->getMessage()."\n";
}
} else {
echo 'The author is valid';
}
});
|
Note
Use addGetterConstraint()
to add constraints on getter methods and
addConstraint()
to add constraints on the class itself.
To be able to translate the error messages, you can use the translator
provider and register the messages under the validators
domain:
1 2 3 4 5 6 7 | $app['translator.domains'] = array(
'validators' => array(
'fr' => array(
'This value should be a valid number.' => 'Cette valeur doit être un nombre.',
),
),
);
|
For more information, consult the Symfony Validation documentation.