PHPackages                             initphp/validation - 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. initphp/validation

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

initphp/validation
==================

Fast, dependency-free data validation for PHP with a string rule DSL, callable rules and localized error messages.

2.0.0(3w ago)124812MITPHPPHP &gt;=8.1CI passing

Since Jul 5Pushed 3w ago1 watchersCompare

[ Source](https://github.com/InitPHP/Validation)[ Packagist](https://packagist.org/packages/initphp/validation)[ RSS](/packages/initphp-validation/feed)WikiDiscussions main Synced today

READMEChangelog (2)Dependencies (4)Versions (4)Used By (2)

InitPHP Validation
==================

[](#initphp-validation)

Fast, dependency-free data validation for PHP. Describe what each field should look like with a small rule DSL (`"required|integer|range(1...10)"`), callbacks, or custom named rules, and get back localized error messages.

[![CI](https://github.com/InitPHP/Validation/actions/workflows/ci.yml/badge.svg)](https://github.com/InitPHP/Validation/actions/workflows/ci.yml)[![Latest Stable Version](https://camo.githubusercontent.com/18a60d2db0cdad8b4e543ece4261cad65a7c344232739cf5dac23bc037780cd2/687474703a2f2f706f7365722e707567782e6f72672f696e69747068702f76616c69646174696f6e2f76)](https://packagist.org/packages/initphp/validation) [![Total Downloads](https://camo.githubusercontent.com/23b35b6802d8a54628808ec3f8e02ed75e08b9a160bb4c49a986ae5f6fc0d297/687474703a2f2f706f7365722e707567782e6f72672f696e69747068702f76616c69646174696f6e2f646f776e6c6f616473)](https://packagist.org/packages/initphp/validation) [![License](https://camo.githubusercontent.com/cd8dd4eeb954463ef381c59ad22e3515d95308b6e32c42b8b2a14886c19a9a76/687474703a2f2f706f7365722e707567782e6f72672f696e69747068702f76616c69646174696f6e2f6c6963656e7365)](https://packagist.org/packages/initphp/validation) [![PHP Version Require](https://camo.githubusercontent.com/771755f96884b64a1683fe33dc340cf88e4aa5b6992f6e744fa81cc5d30f3110/687474703a2f2f706f7365722e707567782e6f72672f696e69747068702f76616c69646174696f6e2f726571756972652f706870)](https://packagist.org/packages/initphp/validation)

- [Documentation](./docs/README.md)
- [Changelog](./CHANGELOG.md)

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

[](#requirements)

- PHP 8.1 or higher
- `ext-mbstring`

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

[](#installation)

```
composer require initphp/validation
```

Quick start
-----------

[](#quick-start)

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

use InitPHP\Validation\Validation;

// GET /?name=Muhammet&year=2022
$validation = new Validation($_GET);

$validation->rule('name', 'required|string');
$validation->rule('year', 'integer|range(1970...2099)');

if ($validation->validation()) {
    // ... the data is valid
} else {
    foreach ($validation->getError() as $message) {
        echo $message . "\n";
    }
}
```

How it works
------------

[](#how-it-works)

1. **Give it data.** Pass an associative array to the constructor, or use `setData()` / `mergeData()`.
2. **Queue rules.** Each `rule()` call adds checks for one or more fields.
3. **Validate.** `validation()` runs every queued rule, returns `true` when nothing failed, and **consumes** the queued rules — so the usual flow is *queue → validate → read errors*, repeated as needed.
4. **Read errors.** `getError()` returns the messages from the most recent run.

```
$validation = new Validation([
    'email'    => 'someone@example.com',
    'password' => 'secret',
    'confirm'  => 'secret',
]);

$valid = $validation
    ->rule('email', 'required|mail')
    ->rule('password', 'required|length(8...)')
    ->rule('confirm', 'again(password)')
    ->validation();
```

Rules
-----

[](#rules)

A rule string is a pipe-separated list. Arguments go in parentheses and are comma-separated; arguments are trimmed, so `only(a, b, c)` and `only(a,b,c)` are equivalent. Rule names are matched case-insensitively.

RuleDescription`required`The value is present and not a blank string (numbers and non-empty arrays pass).`optional`Pseudo-rule. If the field is absent, its other rules are skipped instead of failing.`empty`The value is empty once trimmed.`integer`An integer or an integer-looking string.`float`A float/int or a float-looking string.`numeric`A numeric value.`string`A string.`boolean`A real boolean or one of `true`, `false`, `1`, `0`.`array`An array.`alpha`Letters only (Unicode-aware).`alphanum` / `alphanumeric`Letters and digits only.`mail`A valid e-mail address.`mailHost(host, ...)`A valid e-mail at one of the given hosts.`url`A valid URL.`urlHost(domain, ...)`A URL whose host equals, or is a subdomain of, one of the domains.`ip` / `ipv4` / `ipv6`A valid IP address of the given family.`min(n)`Numbers `>= n`; for strings/arrays the length/count `>= n`.`max(n)`Numbers ` 13]);

$validation->rule('number', static function ($value): bool {
    return ($value % 2) === 0;
}, '{field} must be an even number.');

$validation->validation();            // false
$validation->getError();              // ["number must be an even number."]
```

You can also mix strings and callbacks in one array:

```
$validation->rule('number', ['integer', static fn ($v): bool => $v > 0]);
```

Custom named rules
------------------

[](#custom-named-rules)

Register reusable rules with `extend()` so they work inside the DSL string, arguments and all:

```
$validation->extend(
    'divisible',
    static fn ($value, $by): bool => ((int) $value % (int) $by) === 0,
    '{field} must be divisible by {2}.'
);

$validation->rule('quantity', 'divisible(5)');
```

Optional fields
---------------

[](#optional-fields)

`optional` skips a field's rules when it has no value, but still validates it when present:

```
$validation->rule('nickname', 'optional|alpha|length(3...20)');
```

Named patterns
--------------

[](#named-patterns)

The `regex` rule can reference a named pattern. Built-in names include `uri`, `slug`, `url`, `alpha`, `words`, `alphanum`, `int`, `float`, `tel`, `text`, `file`, `folder`, `address`, `date_dmy`, `date_ymd` and `email`. Register your own with `pattern()`:

```
$validation->pattern('product_code', '[A-Z]{2}-[0-9]{4}');
$validation->rule('code', 'regex(product_code)');
```

Error messages and localization
-------------------------------

[](#error-messages-and-localization)

Messages support `{field}` and positional placeholders: `{1}` is the value and `{2}` is the first rule argument.

```
$validation->rule('age', 'min(18)');
// "age must be greater than or equal to 18."
```

Replace raw field names with friendly labels:

```
$validation->labels(['age' => 'Age']);
// "Age must be greater than or equal to 18."
```

Switch language (the package ships with `en` and `tr`), or override individual messages:

```
$validation->setLocale('tr');
$validation->setLocaleArray(['integer' => '{field} is not a whole number.']);
```

Point at your own language directory with `setLocaleDir()`. See [`docs/localization-and-messages.md`](./docs/localization-and-messages.md).

Exceptions
----------

[](#exceptions)

Everything thrown by the package implements `InitPHP\Validation\Exception\ExceptionInterface`:

- `UndefinedRuleException` — a rule name was used that is neither built-in nor registered with `extend()`. Unknown rules fail loudly instead of silently passing.
- `InvalidArgumentException` — a key or rule entry had an unsupported type.
- `LocaleException` — a locale directory or file could not be loaded.

Upgrading from 1.x
------------------

[](#upgrading-from-1x)

Version 2.0 is a breaking release. The headline changes:

- **Requires PHP 8.1+** (was 7.4+).
- **Callable rules now work** — they previously threw a `TypeError`.
- **Unknown rules now throw** `UndefinedRuleException` instead of silently passing validation.
- **Rules are no longer dispatched to arbitrary global functions** (a surprising and unsafe behaviour). Use `extend()` for custom logic.
- Error-message keys resolve case-insensitively, the `again` message now resolves in English, and several edge cases were fixed (argument trimming, open-ended `length`/`range` bounds, null-safety, loose `equals`/`again`).

Full notes: [`docs/upgrading-from-1.x.md`](./docs/upgrading-from-1.x.md).

Testing
-------

[](#testing)

```
composer test       # PHPUnit
composer stan       # PHPStan (max level)
composer cs-check   # PHP-CS-Fixer (dry run)
composer ci         # all of the above
```

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

[](#contributing)

Contributions are welcome. Please read the org-wide [Contributing guide](https://github.com/InitPHP/.github/blob/main/CONTRIBUTING.md)and open a pull request against `main`. New behaviour should come with tests, and `composer ci` should pass.

Credits
-------

[](#credits)

- [Muhammet ŞAFAK](https://www.muhammetsafak.com.tr) &lt;&gt;

License
-------

[](#license)

Released under the [MIT License](./LICENSE). Copyright © 2022 InitPHP.

###  Health Score

49

—

FairBetter than 94% of packages

Maintenance95

Actively maintained with recent releases

Popularity17

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity59

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

Total

3

Last Release

24d ago

Major Versions

1.x-dev → 2.0.02026-06-10

PHP version history (2 changes)1.0.2PHP &gt;=7.4

2.0.0PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/4b6b34f3ac8938d8ee52ba3bd260680855dc5715c7b2929d9380de30d15a67dd?d=identicon)[muhammetsafak](/maintainers/muhammetsafak)

---

Top Contributors

[![muhammetsafak](https://avatars.githubusercontent.com/u/104234499?v=4)](https://github.com/muhammetsafak "muhammetsafak (5 commits)")

---

Tags

data-validationform-validationinitphpinput-validationphpphp-libraryphp-validationphp-validatorphp8rulessanitizationvalidationvalidatorphpvalidatorvalidationrulesforminputsanitizationinitphp

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/initphp-validation/health.svg)

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

###  Alternatives

[progsmile/request-validator

Simple PHP Request Validator

37114.5k1](/packages/progsmile-request-validator)[iutrace/laravel-cuit-validator

Argentinian CUIT and CUIL Validator

1013.4k](/packages/iutrace-laravel-cuit-validator)

PHPackages © 2026

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