PHPackages                             philiprehberger/php-schema-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. philiprehberger/php-schema-validator

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

philiprehberger/php-schema-validator
====================================

Fluent data schema validator with nested objects, arrays, and dot-notation errors

v1.1.1(4d ago)11MITPHPPHP ^8.2CI passing

Since Mar 15Pushed todayCompare

[ Source](https://github.com/philiprehberger/php-schema-validator)[ Packagist](https://packagist.org/packages/philiprehberger/php-schema-validator)[ Docs](https://github.com/philiprehberger/php-schema-validator)[ RSS](/packages/philiprehberger-php-schema-validator/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (3)Versions (6)Used By (0)

PHP Schema Validator
====================

[](#php-schema-validator)

[![Tests](https://github.com/philiprehberger/php-schema-validator/actions/workflows/tests.yml/badge.svg)](https://github.com/philiprehberger/php-schema-validator/actions/workflows/tests.yml)[![Latest Version on Packagist](https://camo.githubusercontent.com/e69bf1d3d2c4979aa97ebc74e06bf912fc74407b9cd87e942e003928910b2b93/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7068696c69707265686265726765722f7068702d736368656d612d76616c696461746f722e737667)](https://packagist.org/packages/philiprehberger/php-schema-validator)[![License](https://camo.githubusercontent.com/db62caffd94137d5f13e5bcb72ba0b4197135130db445d51641b6995cf47a570/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f7068696c69707265686265726765722f7068702d736368656d612d76616c696461746f72)](LICENSE)

Fluent data schema validator with nested objects, arrays, and dot-notation errors.

---

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

[](#requirements)

DependencyVersionPHP^8.2No external dependencies required.

---

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

[](#installation)

```
composer require philiprehberger/php-schema-validator
```

---

Usage
-----

[](#usage)

```
use PhilipRehberger\SchemaValidator\Schema;

$schema = Schema::object([
    'name'  => Schema::string()->min(1)->max(100),
    'email' => Schema::string()->email(),
    'age'   => Schema::int()->min(0)->max(150),
]);

$result = $schema->validateData([
    'name'  => 'Alice',
    'email' => 'alice@example.com',
    'age'   => 30,
]);

$result->passes(); // true
$result->fails();  // false
$result->errors(); // []
```

### Nested Objects

[](#nested-objects)

```
$schema = Schema::object([
    'user' => Schema::object([
        'profile' => Schema::object([
            'email' => Schema::string()->email(),
        ]),
    ]),
]);

$result = $schema->validateData([
    'user' => ['profile' => ['email' => 'invalid']],
]);

$result->errors(); // ["user.profile.email must be a valid email address"]
```

### Typed Arrays

[](#typed-arrays)

```
$schema = Schema::object([
    'tags'  => Schema::arrayOf(Schema::string()),
    'items' => Schema::arrayOf(Schema::object([
        'id'   => Schema::int(),
        'name' => Schema::string(),
    ])),
]);
```

### Optional and Nullable Fields

[](#optional-and-nullable-fields)

```
$schema = Schema::object([
    'name'     => Schema::string(),
    'nickname' => Schema::string()->optional(),  // field may be absent
    'bio'      => Schema::string()->nullable(),  // field may be null
]);
```

### String Validators

[](#string-validators)

```
Schema::string()->min(3)->max(50);   // length constraints
Schema::string()->email();           // email format
Schema::string()->url();             // URL format
Schema::string()->uuid();            // UUID format
Schema::string()->regex('/^\d+$/');  // custom pattern
```

### Enum Values

[](#enum-values)

```
Schema::enum(['draft', 'published', 'archived']);
```

### Any Value

[](#any-value)

```
Schema::any();           // accepts any non-null value
Schema::any()->nullable(); // accepts anything including null
```

### Custom Validation Rules

[](#custom-validation-rules)

Add custom validation logic to any schema type using `custom()`. The callable receives the value and returns `null` if valid, or an error message string if invalid.

```
$schema = Schema::object([
    'username' => Schema::string()->min(3)->custom(function (string $value): ?string {
        if (str_starts_with($value, 'admin')) {
            return 'must not start with "admin"';
        }

        return null;
    }),
    'age' => Schema::int()->min(0)->custom(function (int $value): ?string {
        if ($value % 2 !== 0) {
            return 'must be an even number';
        }

        return null;
    }),
]);

$result = $schema->validateData(['username' => 'admin_user', 'age' => 25]);
$result->errors();
// ["username must not start with "admin"", "age must be an even number"]
```

Custom validators only run when all built-in checks pass.

### Value Transformers

[](#value-transformers)

Use `transform()` to normalize a value before validation. The callable receives the raw value and returns the transformed value.

```
$schema = Schema::object([
    'email' => Schema::string()->email()->transform(fn (mixed $v) => strtolower(trim($v))),
    'tags'  => Schema::arrayOf(Schema::string())->transform(fn (mixed $v) => array_unique($v)),
]);

$result = $schema->validateData([
    'email' => '  Alice@Example.COM  ',
    'tags'  => ['php', 'laravel', 'php'],
]);

$result->passes(); // true — email was trimmed and lowered before validation
```

Transformers run before any type or constraint checks (but after the null check).

### Cross-Field Validation

[](#cross-field-validation)

Use `crossField()` on an `ObjectSchema` to validate relationships between fields. Each callable receives the full data array and returns `null` if valid, or an error message string.

```
$schema = Schema::object([
    'password'         => Schema::string()->min(8),
    'password_confirm' => Schema::string(),
    'start_date'       => Schema::string(),
    'end_date'         => Schema::string(),
])->crossField(function (array $data): ?string {
    if ($data['password'] !== $data['password_confirm']) {
        return 'password_confirm must match password';
    }

    return null;
})->crossField(function (array $data): ?string {
    if ($data['start_date'] >= $data['end_date']) {
        return 'end_date must be after start_date';
    }

    return null;
});

$result = $schema->validateData([
    'password'         => 'secret123',
    'password_confirm' => 'different',
    'start_date'       => '2026-03-20',
    'end_date'         => '2026-03-10',
]);

$result->errors();
// ["password_confirm must match password", "end_date must be after start_date"]
```

Cross-field validators only run when all individual field validations pass.

---

API
---

[](#api)

### `Schema` (static factory)

[](#schema-static-factory)

MethodReturnsDescription`Schema::object(array $fields)``ObjectSchema`Create an object schema with field definitions`Schema::string()``StringSchema`Create a string schema`Schema::int()``IntSchema`Create an integer schema`Schema::float()``FloatSchema`Create a float schema`Schema::bool()``BoolSchema`Create a boolean schema`Schema::arrayOf(SchemaType $item)``ArraySchema`Create a typed array schema`Schema::enum(array $values)``EnumSchema`Create an enum schema`Schema::any()``AnySchema`Create a schema that accepts any value### `ValidationResult`

[](#validationresult)

MethodReturnsDescription`passes()``bool`True if validation passed`fails()``bool`True if validation failed`errors()``array`All error messages`firstError()``?string`First error message or null### `ObjectSchema` extras

[](#objectschema-extras)

MethodDescription`crossField(callable $validator)`Add a cross-field validator (receives full data array, returns `?string`)### Common Modifiers

[](#common-modifiers)

All schema types support:

MethodDescription`optional()`Field may be absent from the parent object`nullable()`Field may be null`custom(callable $validator)`Add a custom validation callback (receives value, returns `?string`)`transform(callable $transformer)`Transform the value before validation---

Development
-----------

[](#development)

```
composer install
vendor/bin/phpunit
vendor/bin/pint --test
vendor/bin/phpstan analyse
```

License
-------

[](#license)

MIT

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance100

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

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

Total

5

Last Release

4d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/cfd7d24cbbf32400fa13ce0bbe7a31edd2d66a6d4488eafdb3d64c5337bf0435?d=identicon)[philiprehberger](/maintainers/philiprehberger)

---

Top Contributors

[![philiprehberger](https://avatars.githubusercontent.com/u/8218077?v=4)](https://github.com/philiprehberger "philiprehberger (7 commits)")

---

Tags

phpschemavalidatorvalidationfluent

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/philiprehberger-php-schema-validator/health.svg)

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

###  Alternatives

[opis/json-schema

Json Schema Validator for PHP

64135.0M145](/packages/opis-json-schema)[evaisse/php-json-schema-generator

A JSON Schema Generator.

18293.6k1](/packages/evaisse-php-json-schema-generator)

PHPackages © 2026

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