PHPackages                             h2lsoft/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. h2lsoft/validator

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

h2lsoft/validator
=================

Fluent data validator with chainable rules and i18n support

v2.0.0(2mo ago)2621MITPHPPHP &gt;=7.4

Since May 3Pushed 2mo ago1 watchersCompare

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

READMEChangelog (9)DependenciesVersions (10)Used By (1)

Validator
=========

[](#validator)

A fluent, chainable PHP data validator with built-in internationalization support.

[![Version](https://camo.githubusercontent.com/86de2aed79bbfaaf5d6b51ec1cf19f3f8fe414a5aad6772cfa326811bed64413/68747470733a2f2f62616467652e667572792e696f2f67682f68326c736f667425324676616c696461746f722e737667)](https://badge.fury.io/gh/h2lsoft%2Fvalidator)

Requirements
------------

[](#requirements)

- PHP &gt;= 7.4 (PHP 8+ recommended)
- ext-mbstring

Installation
------------

[](#installation)

Install via [Composer](https://getcomposer.org):

```
composer require h2lsoft/validator
```

Quick Start
-----------

[](#quick-start)

```
$validator = new \h2lsoft\Data\Validator();

$validator->input('name')->required()->alpha(' ');
$validator->input('email', 'email address')->required()->email();
$validator->input('age')->required()->integer()->between(18, 99);

if($validator->fails())
{
    print_r($validator->result());
}
```

Usage
-----

[](#usage)

### Creating a validator

[](#creating-a-validator)

```
// default: locale 'en', data from $_POST
$v = new \h2lsoft\Data\Validator();

// with locale
$v = new \h2lsoft\Data\Validator('fr');

// with custom data
$v = new \h2lsoft\Data\Validator('en', ['name' => 'John', 'age' => 25]);
```

### Defining rules

[](#defining-rules)

Chain rules fluently after selecting an input with `input()`:

```
$v->input('email', 'Email address')->required()->email();
$v->input('zip_code', 'Zip code')->required()->mask('99999');
$v->input('password')->required()->minLength(8);
$v->input('password_confirm')->required()->sameAs('password');
$v->input('age')->required()->integer()->between(18, 120);
$v->input('website')->url();
$v->input('start_date')->date('Y-m-d');
$v->input('config')->json();
```

### Checking results

[](#checking-results)

```
if($v->success())
{
    // validation passed
}

if($v->fails())
{
    $result = $v->result();
    // $result['error']            => true/false
    // $result['error_count']      => int
    // $result['error_stack']      => ['message 1', 'message 2', ...]
    // $result['error_stack_html'] => HTML formatted errors
    // $result['error_stack_deep'] => ['field_name' => ['message 1', ...]]
    // $result['error_fields']     => ['field1', 'field2', ...]
}
```

### Custom error messages

[](#custom-error-messages)

Every rule accepts an optional `$message` parameter:

```
$v->input('name')->required('Please enter your name');
$v->input('age')->integer(true, 'Age must be a positive number');
```

Use `[FIELD]` placeholder to reference the field label:

```
$v->input('email', 'Email')->required('`[FIELD]` cannot be empty');
// => "`Email` cannot be empty"
```

### Custom errors

[](#custom-errors)

```
$v->addError('Something went wrong', [], 'field_name');
```

### Custom validation with callbacks

[](#custom-validation-with-callbacks)

Use `custom()` for business logic that doesn't fit standard rules:

```
// check that a promo code exists in database
$v->input('promo_code')->required()->custom(function($value) {
    return PromoCode::findOne(['code' => $value]) !== null;
}, 'Invalid promo code');

// check that an email is not already taken
$v->input('email')->required()->email()->custom(function($value) {
    return User::count(['email' => $value]) === 0;
}, '`[FIELD]` is already taken');

// business rule: minimum amount depends on country
$v->input('amount')->required()->float()->custom(function($value) {
    $minimums = ['FR' => 10, 'US' => 5, 'UK' => 8];
    return $value >= ($minimums[$_POST['country']] ?? 0);
}, '`[FIELD]` is below the minimum for your country');
```

Available Rules
---------------

[](#available-rules)

### String / Value Rules

[](#string--value-rules)

RuleDescriptionExample`required($msg)`Must be present and not empty`->required()``email($msg)`Must be a valid email`->email()``mask($mask, $msg)`Must match a mask (`9`=digit, `a`=letter, `*`=any)`->mask('99-aaa')``in($list, $msg)`Value must be in the list`->in(['a', 'b', 'c'])``notIn($list, $msg)`Value must not be in the list`->notIn(['x', 'y'])``integer($unsigned, $msg)`Must be an integer`->integer()``float($unsigned, $msg)`Must be a float`->float(false)``min($min, $msg)`Value &gt;= min (or array count)`->min(1)``max($max, $msg)`Value &lt;= max (or array count)`->max(100)``between($min, $max, $msg)`Value between min and max`->between(1, 10)``length($len, $msg)`Exact character length`->length(5)``minLength($len, $msg)`Minimum character length`->minLength(3)``maxLength($len, $msg)`Maximum character length`->maxLength(255)``equal($value, $msg)`Must equal a given value`->equal('yes')``accepted($msg)`Must be `'yes'`, `'YES'` or `1``->accepted()``boolean($msg)`Must be a boolean-like value (true/false/1/0/yes/no)`->boolean()``password($min, $upper, $digit, $special, $msg)`Password strength validation`->password(8, true, true, true)``url($flags, $msg)`Must be a valid URL`->url()``alpha($exc, $latin, $min, $cap, $msg)`Alphabetic only`->alpha(' -')``alphaNumeric($exc, $latin, $min, $cap, $msg)`Alphanumeric only`->alphaNumeric('_')``date($format, $msg)`Valid date`->date('d/m/Y')``datetime($format, $msg)`Valid datetime`->datetime('d/m/Y H:i')``dateBefore($date, $format, $msg)`Must be before a given date`->dateBefore('2025-12-31', 'Y-m-d')``dateAfter($date, $format, $msg)`Must be after a given date`->dateAfter(date('Y-m-d'), 'Y-m-d')``time($format, $msg)`Valid time`->time('H:i')``timezone($msg)`Valid timezone identifier`->timezone()``country($msg)`Valid ISO 3166-1 alpha-2 country code`->country()``language($msg)`Valid ISO 639-1 language code`->language()``currency($msg)`Valid ISO 4217 currency code`->currency()``iban($msg)`Valid IBAN with MOD-97 checksum`->iban()``bic($msg)`Valid BIC/SWIFT code (8 or 11 chars)`->bic()``uuid($msg)`Valid UUID (RFC 4122, v1-v5)`->uuid()``macAddress($msg)`Valid MAC address (colon or hyphen)`->macAddress()``cssColor($msg)`Valid CSS color (hex, rgb, hsl, named)`->cssColor()``regex($pattern, $msg)`Must match a regex`->regex('/^\d+$/', 'Digits only')``notRegex($pattern, $msg)`Must not match a regex`->notRegex('/admin/i', 'Forbidden')``ip($flags, $msg)`Valid IP address`->ip()``ipV4($msg)`Valid IPv4 address`->ipV4()``ipV6($msg)`Valid IPv6 address`->ipV6()``json($msg)`Valid JSON string`->json()``jsonArray($msg)`Valid JSON array (`[...]`)`->jsonArray()``jsonObject($msg)`Valid JSON object (`{...}`)`->jsonObject()``sameAs($field, $msg)`Must equal another field's value`->sameAs('password')``different($field, $msg)`Must differ from another field's value`->different('old_password')``requiredIf($field, $value, $msg)`Required only when another field matches`->requiredIf('type', 'pro')``csrfToken($token, $msg, $regenerate)`CSRF token validation (auto-regenerates on failure by default)`->csrfToken()``custom($callback, $msg)`Custom validation via callback`->custom(fn($v) => $v > 10, 'Too low')`### Array Rules (checkboxes, multi-select)

[](#array-rules-checkboxes-multi-select)

RuleDescriptionExample`multiple($msg)`Must be an array`->multiple()``min($min, $msg)`Minimum selections`->min(2)``max($max, $msg)`Maximum selections`->max(5)``between($min, $max, $msg)`Selections between min and max`->between(1, 3)`### File Rules

[](#file-rules)

RuleDescriptionExample`fileRequired($msg)`File must be uploaded`->fileRequired()``fileExtension($ext, $msg)`Allowed extensions`->fileExtension(['jpg', 'png'])``fileMaxSize($size, $msg)`Max file size (kb, mb, gb)`->fileMaxSize('2mb')``fileImage($ext)`Must be an image`->fileImage()``fileMime($mimes, $msg)`Allowed MIME types`->fileMime(['application/pdf'])``fileUploaded($msg)`Must be a real upload`->fileUploaded()``fileImageWidth($w, $strict, $msg)`Image width constraint`->fileImageWidth(800, true)``fileImageHeight($h, $strict, $msg)`Image height constraint`->fileImageHeight(600, true)``fileImageBase64($ext, $create, $msg)`Validate base64 image`->fileImageBase64('png')`Internationalization
--------------------

[](#internationalization)

### Supported locales

[](#supported-locales)

CodeLanguage`en`English (default)`fr`French`es`Spanish`pt`Portuguese`de`German`it`Italian### Setting the locale

[](#setting-the-locale)

```
$v = new \h2lsoft\Data\Validator('fr');

// or after creation
$v->setLocale('es');
```

### Adding custom translations

[](#adding-custom-translations)

```
$v->addLocaleMessages('fr', [
    "`[FIELD]` is required" => "`[FIELD]` est obligatoire",
]);
```

Utility Methods
---------------

[](#utility-methods)

MethodDescription`setData(array $data)`Replace the data to validate`inputGet($name, $default)`Get a value from the data`inputSet($name, $value)`Set a value in the data`inputGetAll()`Get all data values`setInputNames(array $names)`Set display labels for multiple fields`setInputName($name, $label)`Set a display label for one field`hasErrors()`Get the error count`toJson($flags)`Get result as JSON (auto-sets Content-Type header)`reset()`Reset errors and state for reuse with new dataFull Example
------------

[](#full-example)

```
$_POST['name'] = 'the king !';
$_POST['email'] = 'bad@email';
$_POST['zip_code'] = 'a2345';
$_POST['choices'] = ['apple'];
$_POST['job'] = 'webdesigner';
$_POST['days'] = '-50';
$_POST['date'] = '31/20/2020';
$_POST['website'] = 'text.com';
$_POST['config'] = '{"valid": true}';
$_POST['ip'] = '192.168.1.1';
$_POST['conditions'] = 0;

$v = new \h2lsoft\Data\Validator('en');

$v->input('name')->required()->alpha(' ');
$v->input('email', 'email address')->required()->email();
$v->input('zip_code', 'zip code')->required()->mask('99999');
$v->input('choices')->required()->multiple()->in(['banana', 'pear'])->minLength(2);
$v->input('job')->required()->equal('CEO');
$v->input('days')->required()->integer()->between(1, 60);
$v->input('date')->date('m/d/Y');
$v->input('website')->url(FILTER_FLAG_PATH_REQUIRED);
$v->input('config')->json();
$v->input('ip', 'IP address')->ipV4();
$v->input('job')->custom(fn($v) => strlen($v) >= 2, '`[FIELD]` is too short');
$v->input('conditions')->required()->accepted();

if($v->fails())
{
    print_r($v->result());
}
```

License
-------

[](#license)

MIT. See full [license](LICENSE).

###  Health Score

44

—

FairBetter than 92% of packages

Maintenance83

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 100% 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 ~265 days

Recently: every ~334 days

Total

9

Last Release

85d ago

Major Versions

v1.2.2 → v2.0.02026-02-23

### Community

Maintainers

![](https://www.gravatar.com/avatar/5d468c8939398457999795982911155d199461c60812d9eb9673cf3994e78754?d=identicon)[h2lsoft](/maintainers/h2lsoft)

---

Top Contributors

[![h2lsoft](https://avatars.githubusercontent.com/u/959252?v=4)](https://github.com/h2lsoft "h2lsoft (46 commits)")

---

Tags

csrfcsrf-protectiondataformphpvalidatorphpvalidatorvalidationi18ndataform

### Embed Badge

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

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

###  Alternatives

[form-manager/form-manager

PHP-HTML form manager

16041.0k7](/packages/form-manager-form-manager)[progsmile/request-validator

Simple PHP Request Validator

33113.3k1](/packages/progsmile-request-validator)[nilportugues/validator

An efficient data validator for PHP

131.5k](/packages/nilportugues-validator)

PHPackages © 2026

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