PHPackages                             simsoft/validator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. simsoft/validator

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

simsoft/validator
=================

Validator wrapper for Symfony validator

2.0.3(11mo ago)0399MITPHPPHP &gt;=8.2

Since Dec 13Pushed 11mo ago2 watchersCompare

[ Source](https://github.com/sim-soft/validator)[ Packagist](https://packagist.org/packages/simsoft/validator)[ RSS](/packages/simsoft-validator/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (2)Versions (13)Used By (0)

Simsoft Validator
=================

[](#simsoft-validator)

Simsoft/Validator is a wrapper for [symfony/validator](https://symfony.com/doc/current/validation.html) and inspired by Laravel validator.

Install
-------

[](#install)

```
composer require simsoft/validator
```

Basic Usage
-----------

[](#basic-usage)

```
require 'vendor/autoload.php';

use Simsoft\Validator;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Sequentially;

$inputs = $_POST;

$validator = Validator::make($inputs, [
    'email' => new Sequentially([
        new NotBlank(message: 'Email is required'),
        new Email(message: 'Invalid email'),
    ]),
    'password' => [
        new NotBlank(message: 'Password is required'),
        new Length([
            'min' => 8,
            'max' => 20,
            'minMessage' => 'Minimum {{ limit }} characters are required',
            'maxMessage' => 'Maximum {{ limit }} characters exceeded',
        ]),
    ],
]);

if ($validator->passes()) {
    echo 'passed';
    $validated = $validator->validated();                       // get all validated data.
    $email = $validator->validated('email');                    // get email value only.
    $data = $validator->safe()->only(['email', 'password']);    // get only these attributes
    $data = $validator->safe()->except(['remember_me']);        // get all attributes except 'remember_me'.
    $validated = $validator->safe()->all();                     // get all validated data.

    foreach($validator->safe() as $key => $value) {
        ...
    }

} elseif ($valildator->fails()) {
    echo 'failed';

    echo $validator->errors()->first('email');  // Display the email first error message.
    $errors = $validator->errors()->all();      // Retrieve array of all error messages.

    // loop through all 'email' error messages.
    foreach($validator->errors()->get('email') as $message) {
        ...
    }

    // Loop through all error messages.
    foreach($validator->errors() as $key => $messages) {
        foreach($messages as $message) {
            ...
        }
    }
}
```

Custom Validator
----------------

[](#custom-validator)

```
namespace App\Validators;

use Simsoft\Validator;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Sequentially;

class LoginValidator extends Validator
{
    /** @var array Expecting attributes and its default value */
    protected array $attributes ['email', 'password', 'remember_me' => false];

    /**
     * Define the validation rules.
     *
     * @return array The validation rules.
     */
    protected function rules(): array
    {
        return [
            'email' => new Sequentially([
                new NotBlank(['message' => 'Email is required']),
                new Email(['message' => 'Invalid email']),
            ]),
            'password' => [
                new NotBlank(['message' => 'Password is required']),
                new Length([
                    'min' => 8,
                    'max' => 20,
                    'minMessage' => 'Minimum {{ limit }} characters are required',
                    'maxMessage' => 'Maximum {{ limit }} characters exceeded',
                ]),
            ],
        ];
    }
}
```

### Example Usage of Custom Validator

[](#example-usage-of-custom-validator)

```
use App\Validators\LoginValidator;

$inputs = $_POST;

$validator = LoginValidator::make($inputs);
if ($validator->passes()) {
    echo 'passed';
    $data = $validator->validated();
} else {
    echo 'failed';
    print_r($validator->errors()->all());
}
```

Add rule at Runtime
-------------------

[](#add-rule-at-runtime)

You may define constrains as following.

```
use Simsoft\Validator;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Sequentially;

$validator = Validator::make($inputs);

$validator->addRule('password', new Sequentially([
    new NotBlank(['message' => 'Password is required']),
    new Length([
        'min' => 8,
        'max' => 20,
        'minMessage' => 'Minimum {{ limit }} characters are required',
        'maxMessage' => 'Maximum {{ limit }} characters exceeded',
    ]),
]));
```

Constraints
-----------

[](#constraints)

All supported constraints can be found at [Symfony Validation Constraints](https://symfony.com/doc/current/validation.html#constraints)

Validation Group
----------------

[](#validation-group)

Apply only a subset of the validation constraints

```
use Simsoft\Validator;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\PasswordStrength;
use Symfony\Component\Validator\Constraints\Sequentially;

$inputs = $_POST;

$validator = Validator::make($inputs, [
    'email' => new Sequentially([
        new NotBlank(['message' => 'Email is required', 'groups' => ['login', 'register']),
        new Email([
            'message' => 'Invalid email',
            'groups' => ['login', 'register'],
        ]),
    ]),
    'password' => [
        new NotBlank([
            'message' => 'Password is required',
            'groups' => ['login', 'register'],
        ]),
        new Length([
            'min' => 8,
            'max' => 20,
            'minMessage' => 'Minimum {{ limit }} characters are required',
            'maxMessage' => 'Maximum {{ limit }} characters exceeded',
            'groups' => ['login', 'register'],
        ]),
        new PasswordStrength([
            'minScore' => PasswordStrength::STRENGTH_VERY_STRONG,
            'groups' => ['register'],
        ])
    ],
]);

// Apply those constraints belong to 'login' group only.
if ($validator->validate('login')) {
    echo 'Pass';
} else {
    echo 'Failed';
}
```

### Validation Group Sequence

[](#validation-group-sequence)

```
use Symfony\Component\Validator\Constraints\GroupSequence;

$validator = LoginValidator::make($_POST);

// Apply constraints of group 'login', then constraints of group 'strict'.
if ($validator->validate(new GroupSequence(['login', 'strict']))) {
    echo 'Pass';
} else {
    echo 'Failed';
}
```

Make Custom Rule
----------------

[](#make-custom-rule)

Use Simsoft\\Validator\\Rule class to define simple rule.

```
namespace App\Validators;

use Closure;
use Simsoft\Validator;
use Simsoft\Validator\Rule;

$inputs = $_POST;

$validator = Validator::make($inputs, [
    // ...
    'password' => Rule::make(function(mixed $value, Closure $fail) {
        $min = 8;
        $max = 20;

        $length = mb_strlen($value, 'UTF-8');

        if ($length == 0) {
            $fail('Password is required');
        } elseif ($length < $min) {
            $fail(sprintf('Minimum %d characters are required', $min));
        } elseif ($length > $max) {
            $fail(sprintf('Maximum %d characters exceeded', $max));
        } elseif (!preg_match('/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^\da-zA-Z])(.{8,20})$/', $value, $matches)) {
            $fail('Invalid password');
        }
    })
]);
```

Reusable Custom Validator
-------------------------

[](#reusable-custom-validator)

The following create a reusable "Password" validation rule.

```
namespace App\Constraints;

use Closure;
use Simsoft\Validator\Constraints\ValidationRule;

class Password extends ValidationRule
{
    public string $message = 'At least 8 alphanumeric characters which include at least 1 uppercase, 1 lowercase, 1 digit and 1 special characters only.';
    protected string $charset = 'UTF-8';
    protected string $format = '/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^\da-zA-Z])(.{8,20})$/';

    protected int $min;
    protected int $max;

    public function __construct(mixed $options = null, array $groups = null, mixed $payload = null)
    {
        $this->min = $options['min'] ?? 8;
        $this->max = $options['max'] ?? 20;
        $this->format = $options['format'] ?? $this->format;
        $this->message = $options['message'] ?? $this->message;

        parent::__construct($options, $groups, $payload);
    }

    public function validate(mixed $value, Closure $fail): void
    {
        $length = mb_strlen($value, $this->charset);

        if ($length == 0) {
            $fail('Password is required');
        } elseif ($length < $this->min) {
            $fail(sprintf('Minimum %d characters are required', $this->min));
        } elseif ($length > $this->max) {
            $fail(sprintf('Maximum %d characters exceeded', $this->max));
        } elseif (!preg_match($this->format, $value, $matches)) {
            $fail($this->message);
        }
    }
}
```

Example usage of Password validation rule.

```
use App\Constraints\Password;
use Simsoft\Validator;

$input = $_POST;

$validator = Validator::make($input, [
    // ...
    'password' => new Password([
        'message' => 'Invalid password',
        'min' => 5,
        'max' => 10,
        'format' => '/new regex pattern/',
        'groups' => ['login'],
    ]),
])

if ($validator->passes()) {
    echo 'Pass';
} else {
    echo 'Failed';
}
```

Advance Custom Validation Constraint
------------------------------------

[](#advance-custom-validation-constraint)

For create advance custom validation constraint, please refer to [How to Create a Custom Validation Constraint](https://symfony.com/doc/current/validation/custom_constraint.html)

Validation Rule Helpers
-----------------------

[](#validation-rule-helpers)

```
use Closure;
use Simsoft\Validator;
use Simsoft\Validator\Rule;

$inputs = $_POST;

$validator = Validator::make($inputs, [
    // ...
    'password' => [
        Rule::make(function(mixed $value, Closure $fail) {
            if (!preg_match('/^w+$/', $value, $matches)) {
                $fail('Invalid password');
            }
        })
    ]

    'password_confirm' => [
        Rule::requiredIf(!empty($inputs['password'])),
        // or
        Rule::requiredIf(!empty($inputs['password']), 'Password confirm is required'),
        // or
        Rule::requiredIf(fn() => !empty($inputs['password'])),
    ],
])
```

License
-------

[](#license)

The Simsoft Validator is licensed under the MIT License. See the [LICENSE](LICENSE) file for details

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance50

Moderate activity, may be stable

Popularity13

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity65

Established project with proven stability

 Bus Factor1

Top contributor holds 80% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~99 days

Recently: every ~149 days

Total

10

Last Release

354d ago

Major Versions

1.0.5 → 2.0.02024-06-10

PHP version history (4 changes)1.0.0PHP ^8.1|^8.2

1.0.4PHP ^8.1

2.0.0PHP ^8

2.0.1PHP &gt;=8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/7c3e6315469b56ed1797318e31e05bcddb12dba268488a2fb0cd2b43971c9ac3?d=identicon)[vzangloo](/maintainers/vzangloo)

---

Top Contributors

[![vzangloo](https://avatars.githubusercontent.com/u/1908200?v=4)](https://github.com/vzangloo "vzangloo (16 commits)")[![sim-soft](https://avatars.githubusercontent.com/u/118705222?v=4)](https://github.com/sim-soft "sim-soft (4 commits)")

---

Tags

phpsymfonyvalidatorsimsoft

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/simsoft-validator/health.svg)

```
[![Health](https://phpackages.com/badges/simsoft-validator/health.svg)](https://phpackages.com/packages/simsoft-validator)
```

###  Alternatives

[rollerworks/password-strength-validator

Password-strength validator for Symfony

1455.7M6](/packages/rollerworks-password-strength-validator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
