Skip to content

Instantly share code, notes, and snippets.

@webmozart
Last active June 25, 2023 23:30
Show Gist options
  • Save webmozart/8473598 to your computer and use it in GitHub Desktop.
Save webmozart/8473598 to your computer and use it in GitHub Desktop.
A little experiment: Validating (potentially multi-leveled) arrays with the Symfony2 Validator component and returning the errors in the same data structure as the validated array by using the Symfony2 PropertyAccess component.
<?php
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\Validator\Constraints\All;
use Symfony\Component\Validator\Constraints\Choice;
use Symfony\Component\Validator\Constraints\Collection;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Optional;
use Symfony\Component\Validator\Constraints\Required;
use Symfony\Component\Validator\Constraints\Type;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\Validator\Validation;
require_once __DIR__.'/vendor/autoload.php';
$validator = Validation::createValidator();
$propertyAccessor = PropertyAccess::createPropertyAccessor();
$array = array(
'firstName' => 'Be',
'hobbies' => array(
array(
'name' => 'Hiking',
'frequency' => 'monthly',
),
array(
'name' => 'Cooking',
),
)
);
// Validate values
$constraint = new Collection(array(
'firstName' => new Required(array(
new NotBlank(),
new Length(array('min' => 3)),
)),
'lastName' => new Required(array(
new NotBlank(),
new Length(array('min' => 3)),
)),
'hobbies' => new Optional(array(
new Type('array'),
new All(
new Collection(array(
'name' => new Required(array(
new NotBlank(),
new Length(array('min' => 3)),
)),
'frequency' => new Required(array(
new Choice(array('daily', 'weekly', 'monthly')),
))
))
),
)),
));
$violations = $validator->validateValue($array, $constraint);
// Use the same structure for the errors
$errors = array();
foreach ($violations as $violation) {
/** @var ConstraintViolationInterface $violation */
$entryErrors = (array) $propertyAccessor->getValue($errors, $violation->getPropertyPath());
$entryErrors[] = $violation->getMessage();
$propertyAccessor->setValue($errors, $violation->getPropertyPath(), $entryErrors);
}
var_export($errors);
echo "\n";
array (
'firstName' =>
array (
0 => 'This value is too short. It should have 3 characters or more.',
),
'lastName' =>
array (
0 => 'This field is missing.',
),
'hobbies' =>
array (
1 =>
array (
'frequency' =>
array (
0 => 'This field is missing.',
),
),
),
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment