spiral-packages/symfony-validator
Symfony Validator bridge for the Spiral Framework. Integrates Symfony’s validation component into Spiral apps, providing familiar constraints and error handling. Includes CI, static analysis, and type coverage. Documentation available at spiral.dev.
Installation
composer require spiral-packages/symfony-validator:^1.5.0
Add the package to your Spiral Framework bootstrap.php:
$container->set(SymfonyValidator::class, fn() => new SymfonyValidator());
First Use Case: Basic Validation (Symfony 7.0 Compatible) Define a validator in a command or controller:
use Spiral\Validator\ValidatorInterface;
use Spiral\Validator\Rule\StringRule;
$validator = $container->get(ValidatorInterface::class);
$result = $validator->validate([
'name' => 'John Doe',
'email' => 'invalid-email'
], [
'name' => [new StringRule(['min' => 2])],
'email' => [new StringRule(['email' => true])]
]);
Key Files to Review
src/ValidatorInterface.php (Core interface)src/SymfonyValidator.php (Updated bridge for Symfony 7.0)src/Rule/ (Predefined rules, now compatible with Symfony 7.0 constraints)src/Constraint/ (Newly added or updated Symfony constraint mappings)Use with Spiral's HTTP layer for incoming requests:
use Spiral\Http\Middleware\ValidationMiddleware;
$middleware = new ValidationMiddleware(
$validator,
[
'email' => [new StringRule(['email' => true])],
'age' => [new NumericRule(['min' => 18])]
]
);
Validate domain entities before persistence:
$user = new User($data);
$result = $validator->validateObject($user, [
'email' => [new StringRule(['email' => true])],
'password' => [new StringRule(['min' => 8])]
]);
Build rules programmatically:
$rules = [];
if ($isAdmin) {
$rules['role'] = [new InRule(['values' => ['admin']])];
}
$validator->validate($data, $rules);
Extend Symfony 7.0 constraints for Spiral:
use Symfony\Component\Validator\Constraint;
use Spiral\Validator\Rule\CustomRule;
class UniqueUsernameRule extends CustomRule {
protected function getSymfonyConstraint(): Constraint {
return new \Symfony\UX\Validator\Constraints\UniqueEntity(['entity' => User::class, 'fields' => 'username']);
}
}
Bind validator to specific contexts (e.g., CLI vs. HTTP):
$container->bindInterface(
ValidatorInterface::class,
fn() => new SymfonyValidator(['context' => 'cli'])
);
Leverage Symfony 7.0's new constraints (e.g., Url, Ipv4, Ipv6):
use Spiral\Validator\Rule\UrlRule;
$rules = [
'website' => [new UrlRule()]
];
Rule Mismatch (Symfony 7.0 Updates)
NotBlank → NotNull for certain types).CustomRule for complex Symfony 7.0 constraints or check the Symfony 7.0 migration guide.Lazy Loading
UndefinedIndex if data keys don’t match rules.null as default for missing fields:
$result = $validator->validate(array_merge($data, ['missing_field' => null]), $rules);
Performance
$compiled = $validator->compileRules($rules);
$validator->validate($data, $compiled);
Doctrine Integration (Symfony 7.0)
UniqueEntity, ensure Doctrine is loaded first and compatible with Symfony 7.0:
$container->set(DoctrineValidator::class, fn() => new DoctrineValidator($entityManager));
$validator->validate($data, $rules, ['groups' => ['default', 'strict']]);
$compiled = $validator->compileRules($rules);
var_dump($compiled);
$symfonyValidator = $container->get(SymfonyValidator::class)->getValidator();
$symfonyValidator->validate($data, $constraints);
Custom Error Messages Override Symfony's messages in Spiral's rules:
new StringRule(['min' => 3, 'message' => 'Name must be at least 3 characters.']);
Validation Groups (Symfony 7.0) Use Symfony 7.0's groups for modular validation:
$validator->validate($data, $rules, ['groups' => ['registration', 'profile']]);
Event Listeners Attach Spiral events to validation:
$container->pipe(
OnValidateEvent::class,
fn(OnValidateEvent $event) => $event->setData($this->sanitize($event->getData()))
);
Testing Mock the validator in tests:
$validatorMock = Mockery::mock(ValidatorInterface::class);
$validatorMock->shouldReceive('validate')->andReturn(['errors' => []]);
$container->set(ValidatorInterface::class, $validatorMock);
Symfony 7.0 Constraint Updates
Length → StringLength):
use Spiral\Validator\Rule\StringLengthRule;
$rules = ['name' => [new StringLengthRule(['max' => 50])]];
New Symfony 7.0 Features
Expression constraint for complex logic:
use Spiral\Validator\Rule\ExpressionRule;
$rules = ['age' => [new ExpressionRule('this > 18', 'You must be over 18.')]];
How can I help you explore Laravel packages today?