A Symfony Validator wrapper that enables fluent-style validation for raw values, offering an easy-to-use and intuitive API to validate user input or other data in a concise and readable manner.
- π Fluent-style validation: Chain validation methods for better readability and flow.
- π€ Constraints autocompletion: Enables IDE autocompletion for available constraints.
- π₯ Three validation methods: Use
validate
,assert
, orisValid
based on the context (i.e., collect errors or throw exceptions). - βοΈ Custom constraints: Easily integrate custom validation logic with Symfony's Validator system.
- π¬ Translations support: Translate validation error messages into multiple languages.
- PHP 8.2 or higher.
Install via Composer:
composer require programmatordev/fluent-validator
Simple usage example:
use ProgrammatorDev\FluentValidator\Validator;
// example: validate the user's age to ensure it's between 18 and 60
$errors = Validator::notBlank()
->greaterThanOrEqual(18)
->lessThan(60)
->validate($age);
if ($errors->count() > 0) {
// handle errors
}
Constraints autocompletion is available in IDEs like PhpStorm. The method names match Symfony constraints but with a lowercase first letter:
NotBlank
=>notBlank
All
=>all
PasswordStrength
=>passwordStrength
- ...and so on.
For all available constraints, check the Constraints section.
For all available methods, check the Methods section.
There is also a section for Custom Constraints and Translations.
All available constraints can be found on the Symfony Validator documentation.
For custom constraints, check the Custom Constraints section.
use Symfony\Component\Validator\Constraints\GroupSequence;
validate(mixed $value, ?string $name = null, string|GroupSequence|array|null $groups = null): ConstraintViolationListInterface
Returns a ConstraintViolationList
object, acting as an array of errors.
use ProgrammatorDev\FluentValidator\Validator;
$errors = Validator::email()->validate('test@email.com');
if ($errors->count() > 0) {
foreach ($errors as $error) {
$message = $error->getMessage();
// ...
}
}
use Symfony\Component\Validator\Constraints\GroupSequence;
assert(mixed $value, ?string $name = null, string|GroupSequence|array|null $groups = null): void
Throws a ValidationFailedException
when validation fails.
use ProgrammatorDev\FluentValidator\Exception\ValidationFailedException;
use ProgrammatorDev\FluentValidator\Validator;
try {
Validator::notBlank()->assert($name);
Validator::notBlank()->email()->assert($email);
}
catch (ValidationFailedException $exception) {
// exception message will always be the first error thrown
$message = $exception->getMessage();
// value that failed validation
$value = $exception->getInvalidValue();
// get access to all errors
// returns a ConstraintViolationList object like in the validate method
$errors = $exception->getViolations();
// ...
}
use Symfony\Component\Validator\Constraints\GroupSequence;
isValid(mixed $value, string|GroupSequence|array|null $groups = null): bool
Returns a bool
indicating if the value is valid.
use ProgrammatorDev\FluentValidator\Validator;
if (!Validator::email()->isValid($email)) {
// handle invalid email
}
use Symfony\Component\Validator\Constraint;
/** @return Constraint[] */
getConstraints(): array
Returns an array with all added constraints.
use ProgrammatorDev\FluentValidator\Validator;
$constraints = Validator::notBlank()->email()->getConstraints();
It is useful for Composite
constraints (i.e., a constraint that is composed of other constraints)
and keeps the fluent-style validation:
use ProgrammatorDev\FluentValidator\Validator;
// validate that array should have at least one value
// and each value should be between 0 and 100
$errors = Validator::count(min: 1)
->all(Validator::range(min: 0, max: 100)->getConstraints())
->validate($value);
addNamespace(string $namespace): void
Used to add namespaces for custom constraints.
Check the Custom Constraints section.
use Symfony\Contracts\Translation\TranslatorInterface;
setTranslator(?TranslatorInterface $translator): void
Used to add a translator for validation error message translations.
Check the Translations section.
If you need a custom constraint, follow the Symfony Validator documentation: Creating Custom Constraints.
This class defines the error message and configurable options.
namespace App\Constraint;
use Symfony\Component\Validator\Constraint;
class ContainsAlphanumeric extends Constraint
{
// set configurable options
}
The validator checks if the value complies with the constraint rules.
namespace App\Constraint;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class ContainsAlphanumericValidator extends ConstraintValidator
{
public function validate(mixed $value, Constraint $constraint): void
{
// custom validation logic
}
}
Register the namespace where the custom constraints will be located in your project.
use ProgrammatorDev\FluentValidator\Validator;
Validator::addNamespace('App\Constraint');
Validator::notBlank()->containsAlphanumeric()->isValid('!'); // false
Validator::notBlank()->containsAlphanumeric()->isValid('v4l1d'); // true
You can have multiple constraints in the same namespace or have multiple namespaces.
Note
Custom constraints will not be suggested in IDE autocompletion.
Set a global translator to handle error message translations.
use ProgrammatorDev\FluentValidator\Translator\Translator;
// set translator to Portuguese (Portugal) locale
Validator::setTranslator(new Translator('pt'));
// now all error messages will be in Portuguese
Validator::notBlank()->validate('');
To add your own translations, you can integrate a custom translator.
Any form of contribution to improve this library (including requests) will be welcome and appreciated. Make sure to open a pull request or issue.
This project is licensed under the MIT license. Please see the LICENSE file distributed with this source code for further information regarding copyright and licensing.