PHPackages                             gravity/dataverify - 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. gravity/dataverify

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

gravity/dataverify
==================

A lightweight PHP validation library with fluent interface for validating data structures, supporting batch/fail-fast modes and custom strategies

v1.1.0(4mo ago)1228MITPHPPHP &gt;=8.1

Since Dec 28Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/gravity-zero/dataVerify)[ Packagist](https://packagist.org/packages/gravity/dataverify)[ Docs](https://github.com/gravity-zero/dataverify)[ RSS](/packages/gravity-dataverify/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (4)Dependencies (5)Versions (8)Used By (0)

DataVerify
==========

[](#dataverify)

A fluent, zero-dependency PHP validation library.

[![Latest Version](https://camo.githubusercontent.com/30d90d9362d83d0e51a66e3a33c24aaaffea9cee8372e92bef9a3d000fd30bf2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f677261766974792f646174617665726966792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gravity/dataverify)[![Total Downloads](https://camo.githubusercontent.com/917608d596b77a2b6eb468c14e9ffaac3f38e8e453d9043b14645b5b7ba8c7ac/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f677261766974792f646174617665726966792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gravity/dataverify)[![PHP Version](https://camo.githubusercontent.com/6518db1335bf20fdff07253dc6d6d0cec955b5fb6a8ef1382ac6d73687ecc07f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e312d626c7565)](https://www.php.net/)[![License](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)](LICENCE)

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

[](#requirements)

- PHP 8.1+
- Composer (recommended) or manual installation

```
composer require gravity/dataverify
```

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

[](#quick-start)

```
use Gravity\DataVerify;

$data = (object)[
    'email' => 'user@example.com',
    'age' => 25
];

$dv = new DataVerify($data);
$dv
    ->field('email')->required->email
    ->field('age')->required->int->between(18, 100);

if (!$dv->verify()) {
    print_r($dv->getErrors());
}
```

Key Features
------------

[](#key-features)

**Fluent validation**

```
$dv->field('email')->required->email->maxLength(100);
```

**Nested objects**

```
$dv->field('user')->required->object
    ->subfield('name')->required->string
    ->subfield('email')->required->email;
```

**Conditional validation**

```
$dv->field('vat_number')
    ->when('country', '=', 'FR')
    ->then->required->regex('/^FR\d{11}$/');
```

**Reusable Rules &amp; Schemas**

```
// Register reusable validation rules
DataVerify::registerRules('strongPassword')
    ->minLength(12)
    ->containsUpper
    ->containsLower
    ->containsSpecialCharacter;

// Apply to any field
$dv->field('password')->rule('strongPassword');

// Register complete validation schemas
DataVerify::registerSchema('userApi')
    ->field('user')->required->object
        ->subfield('email')->email
            ->when('user.id', '!=', null)->then->required
        ->subfield('password')->rule('strongPassword')
            ->when('user.id', '!=', null)->then->required;

// Apply entire schema
$dv = new DataVerify($data);
$dv->schema('userApi');

if(!$dv->verify()){
    // Get Your Errors
}
```

**Custom validation strategies**

```
class SiretStrategy extends ValidationStrategy {
    public function getName(): string { return 'siret'; }
    protected function handler(mixed $value): bool { /* validation logic */ }
}

DataVerify::global()->register(new SiretStrategy());
$dv->field('siret')->siret; // Available everywhere
```

Use Cases
---------

[](#use-cases)

**REST APIs &amp; Web Services**Perfect for validating incoming API requests with conditional logic:

```
// POST /api/users/register
$data = json_decode(file_get_contents('php://input'));

$dv = new DataVerify($data);
$dv
    ->field('email')->required->email->disposableEmail
    ->field('password')->required->minLength(8)
        ->containsUpper->containsNumber->containsSpecialCharacter
    ->field('company_name')
        ->when('account_type', '=', 'business')
        ->then->required->string->minLength(2)
    ->field('vat_number')
        ->when('account_type', '=', 'business')
        ->and('country', 'in', ['FR', 'BE', 'DE'])
        ->then->required->regex('/^[A-Z]{2}\d{9,12}$/');

if (!$dv->verify(batch: false)) { // Fail-fast for better performance
    http_response_code(400);
    echo json_encode(['errors' => $dv->getErrors()]);
    exit;
}
```

[See full example](examples/api-request.php)

**Form Validation (WordPress, PrestaShop, Laravel)**Validate complex forms with dependent fields:

```
// E-commerce checkout form
$dv = new DataVerify($_POST);
$dv
    ->field('shipping_method')->required->in(['standard', 'express', 'pickup'])
    ->field('shipping_address')
        ->when('shipping_method', '!=', 'pickup')
        ->then->required->string->minLength(10)
    ->field('shipping_city')
        ->when('shipping_method', '!=', 'pickup')
        ->then->required->string
    ->field('pickup_store')
        ->when('shipping_method', '=', 'pickup')
        ->then->required->string
    ->field('gift_message')
        ->when('is_gift', '=', true)
        ->then->required->maxLength(500);

if (!$dv->verify()) {
    // Display errors in form
    foreach ($dv->getErrors() as $error) {
        echo "{$error['message']}";
    }
}
```

[See full example](examples/basic.php)

**Data Processing Pipelines**Validate batches of data with fail-fast for early termination:

```
// Process CSV import with 10,000 rows
foreach ($csvRows as $row) {
    $dv = new DataVerify($row);
    $dv
        ->field('sku')->required->alphanumeric
        ->field('price')->required->numeric->greaterThan(0)
        ->field('stock')->int->between(0, 99999);

    if (!$dv->verify(batch: false)) { // Stop at first error per row
        $failedRows[] = ['row' => $row, 'errors' => $dv->getErrors()];
        continue; // Skip invalid row
    }

    // Process valid row...
}
```

**Conditional Business Rules**Complex validation logic based on multiple conditions:

```
// SaaS subscription validation
$dv = new DataVerify($subscription);
$dv
    ->field('plan')->required->in(['free', 'pro', 'enterprise'])
    ->field('payment_method')
        ->when('plan', '!=', 'free')
        ->then->required->in(['card', 'invoice'])
    ->field('card_number')
        ->when('plan', '!=', 'free')
        ->and('payment_method', '=', 'card')
        ->then->required->regex('/^\d{16}$/')
    ->field('billing_email')
        ->when('plan', '=', 'enterprise')
        ->or('payment_method', '=', 'invoice')
        ->then->required->email
    ->field('seats')
        ->when('plan', 'in', ['pro', 'enterprise'])
        ->then->required->int->between(1, 1000);
```

[See conditional examples](examples/conditional-validation.php)

**Multi-language Applications**Built-in i18n with automatic locale detection:

```
$dv = new DataVerify($data);
$dv->setLocale('fr'); // Built-in: EN, FR

$dv->field('email')->required->email;

if (!$dv->verify()) {
    // Error message in French:
    // "Le champ email doit être une adresse email valide"
    echo $dv->getErrors()[0]['message'];
}

// Add custom translations
$dv->addTranslations([
    'validation.siret' => 'El campo {field} debe ser un SIRET válido'
], 'es');
```

[See translation examples](examples/translation-basic.php)

Why DataVerify?
---------------

[](#why-dataverify)

- ✅ **Zero dependencies** - Pure PHP 8.1+, no vendor bloat
- ✅ **Fluent API** - Readable, chainable validations
- ✅ **Reusable patterns** - Rules &amp; Schemas for DRY validation with auto-documentation
- ✅ **Extensible** - Custom validation strategies with auto-documentation
- ✅ **Fast** - ~9.7μs simple validation, ~2MB memory ([benchmarks](docs/BENCHMARK.md))
- ✅ **i18n ready** - Built-in translation support (EN, FR)
- ✅ **Framework agnostic** - Works with WordPress, Laravel, Symfony, vanilla PHP
- ✅ **Worker-mode ready** - Tested with FrankenPHP, stable memory over 3M+ requests
- ✅ **Production tested** - 600+ tests, 84% mutation score

Documentation
-------------

[](#documentation)

**Guides:**

- [Rules &amp; Schemas](docs/RULES_AND_SCHEMAS.md) - Reusable validation patterns
- [Conditional Validation](docs/CONDITIONAL_VALIDATION.md) - `when/and/or/then` syntax
- [Custom Strategies](docs/CUSTOM_STRATEGIES.md) - Extend with your own rules
- [Internationalization](docs/INTERNATIONALIZATION.md) - Multi-language error messages
- [Error Handling](docs/ERROR_HANDLING.md) - Working with validation errors
- [Validation Rules](docs/VALIDATIONS.md) - All 30+ built-in rules
- [Benchmarks](docs/BENCHMARK.md) - Performance metrics

**Examples:**

- [API Request Validation](examples/api-request.php)
- [Basic Usage](examples/basic.php)
- [Conditional Validation](examples/conditional-validation.php)
- [Custom Validation Rules](examples/custom-validation.php)
- [Reusable Rules](examples/rules.php)
- [Validation Schemas](examples/schema.php)
- [Translation (PHP)](examples/translation-basic.php)
- [Translation (YAML)](examples/translation-yaml.php)

Performance
-----------

[](#performance)

DataVerify is designed for production with predictable sub-millisecond performance:

```
Simple validation:       ~9.7μs   (99% < 10μs)
Complex nested:          ~19.1μs  (99% < 20μs)
Batch mode (100 fields): ~572.9μs
Fail-fast (100 fields):  ~256.1μs (2.2x faster)
Memory usage:            ~2MB     (stable)

```

**See:** [Full benchmarks](docs/BENCHMARK.md)

Examples
--------

[](#examples)

**Basic validation**

```
$dv = new DataVerify($data);
$dv
    ->field('name')->required->string->minLength(3)
    ->field('email')->required->email
    ->field('age')->int->between(18, 120);

if (!$dv->verify()) {
    print_r($dv->getErrors());
}
```

**Batch vs fail-fast**

```
$dv->verify();              // Batch mode: all errors
$dv->verify(batch: false);  // Fail-fast: first error only (2x faster)
```

**Optional fields**

```
$dv->field('phone')->string;  // Optional: null OK, if present must be valid
$dv->field('email')->required->email;  // Required: must exist AND be valid
```

**Custom error messages**

```
$dv->field('password')
    ->required
    ->minLength(8)->errorMessage('Password too weak - min 8 characters')
    ->containsUpper->errorMessage('Password must include uppercase letters');
```

**Nested validation**

```
// Simple object nesting
$dv->field('user')->required->object
    ->subfield('profile')->required->object
        ->subfield('address')->required->object
            ->subfield('city')->required->string
            ->subfield('country')->required->string;

// Deep array nesting with indices
// Validates: data.orders[0].items[2].name
$dv->field('orders')->required->array
    ->subfield('0', 'items', '2', 'name')->required->string->minLength(3);

// Complex nested structures (arrays + objects)
// Validates: data.warehouses[0].inventory[1].product.sku
$dv->field('warehouses')->required->array
    ->subfield('0', 'inventory', '1', 'product', 'sku')->required->alphanumeric
    ->subfield('0', 'inventory', '1', 'product', 'stock')->required->int->between(0, 9999);
```

FAQ
---

[](#faq)

**Is sanitization included?****No.** DataVerify validates data but does NOT sanitize it. Always sanitize user input before validation:

```
$data->email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$data->name = htmlspecialchars($_POST['name'], ENT_QUOTES, 'UTF-8');

$dv = new DataVerify($data);
$dv->field('email')->required->email;
```

**Can I reuse a DataVerify instance?****No.** Each validation requires a new instance to prevent state corruption:

```
// ✅ Correct
foreach ($users as $user) {
    $dv = new DataVerify($user); // New instance
    $dv->field('email')->required->email;
    $dv->verify();
}

// ❌ Wrong - throws LogicException
$dv = new DataVerify($user1);
$dv->verify();
$dv->verify(); // Error: already verified
```

**How do I validate arrays of items?**Loop and validate each item individually:

```
foreach ($data->items as $item) {
    $dv = new DataVerify($item);
    $dv->field('sku')->required->alphanumeric
       ->field('qty')->required->int->between(1, 100);

    if (!$dv->verify()) {
        $errors[] = $dv->getErrors();
    }
}
```

Contributing
------------

[](#contributing)

Contributions welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md) for version history.

License
-------

[](#license)

MIT License - see [LICENSE](LICENCE) file for details.

---

**Made with ❤️ by [Romain Feregotto](https://github.com/gravity-zero)**

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance78

Regular maintenance activity

Popularity14

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 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 ~3 days

Total

7

Last Release

123d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a974078cc9f8a8e034d20e9ff8a078c6fd83c812fa5d2ed66c8b023433c94d2c?d=identicon)[gravity-zero](/maintainers/gravity-zero)

---

Top Contributors

[![gravity-zero](https://avatars.githubusercontent.com/u/54350622?v=4)](https://github.com/gravity-zero "gravity-zero (23 commits)")

---

Tags

batch-validationconditional-validationdata-validationfluent-apiform-validationinput-validationmethod-chainingphpphp8validationvalidatorzero-dependenciesphpvalidatorvalidationform validationdata validationinput-validation

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/gravity-dataverify/health.svg)

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

###  Alternatives

[blakvghost/php-validator

PHPValidator is a modern PHP library for data validation in your PHP applications. It provides a flexible and extensible way to validate data using predefined rules or by creating custom validation rules.

2524.2k2](/packages/blakvghost-php-validator)[bitapps/wp-validator

WordPress Validation and Sanitization Library

127.4k1](/packages/bitapps-wp-validator)

PHPackages © 2026

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