programmatordev/fluent-validator

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.

v0.2.0 2025-04-01 15:09 UTC

This package is auto-updated.

Last update: 2025-04-01 15:10:16 UTC


README

Latest Version Software License Tests

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.

Features

  • 🌊 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, or isValid 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.

Table of Contents

Requirements

  • PHP 8.2 or higher.

Installation

Install via Composer:

composer require programmatordev/fluent-validator

Usage

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.

Constraints

All available constraints can be found on the Symfony Validator documentation.

For custom constraints, check the Custom Constraints section.

Methods

validate

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();
        // ...
    }
}

assert

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();
    
    // ...
}

isValid

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
}

toArray

use Symfony\Component\Validator\Constraint;

/** @return Constraint[] */
toArray(): array

Returns an array with all added constraints.

use ProgrammatorDev\FluentValidator\Validator;

$constraints = Validator::notBlank()->email()->toArray();

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)->toArray())
    ->validate($value);

addNamespace

addNamespace(string $namespace): void

Used to add namespaces for custom constraints.

Check the Custom Constraints section.

setTranslator

use Symfony\Contracts\Translation\TranslatorInterface;

setTranslator(?TranslatorInterface $translator): void

Used to add a translator for validation error message translations.

Check the Translations section.

Custom Constraints

If you need a custom constraint, follow the Symfony Validator documentation: Creating Custom Constraints.

Example: Creating a ContainsAlphanumeric Constraint

1. Create a Constraint Class

This class defines the error message and configurable options.

namespace App\Constraint;

use Symfony\Component\Validator\Constraint;

class ContainsAlphanumeric extends Constraint
{
    // set configurable options
}

2. Create the Validator Class

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
    }
}

3. Register the Constraint Namespace

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.

Translations

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.

Contributing

Any form of contribution to improve this library (including requests) will be welcome and appreciated. Make sure to open a pull request or issue.

License

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.