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

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

lukman-ss/validation
====================

A lightweight standalone PHP Validation package

v1.0.0(1mo ago)1109↓50%1MITPHPPHP &gt;=8.2

Since Jun 14Pushed 1w agoCompare

[ Source](https://github.com/lukman-ss/validation)[ Packagist](https://packagist.org/packages/lukman-ss/validation)[ Docs](https://github.com/lukman-ss/validation)[ RSS](/packages/lukman-ss-validation/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (3)Dependencies (1)Versions (2)Used By (1)

Lukman Validation
=================

[](#lukman-validation)

[![Lukman Validation Hero](docs/hero.jpg)](docs/hero.jpg)

A lightweight standalone PHP validation library with zero external runtime dependencies.

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

[](#requirements)

- PHP 8.2 or higher

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

[](#installation)

Install the package via Composer:

```
composer require lukman-ss/validation
```

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

[](#basic-usage)

Run validation using either standard boolean checks or the exception flow.

```
use Lukman\Validation\Validator;

$data = [
    'username' => 'john_doe',
    'age' => 25,
];

$rules = [
    'username' => 'required|string|min:3',
    'age' => 'required|integer',
];

$validator = new Validator($data, $rules);

if ($validator->passes()) {
    // Get all validated data
    $validated = $validator->validated();
} else {
    // Get validation errors as a MessageBag
    $errors = $validator->errors();
    echo $errors->first('username');
}
```

Exception Flow
--------------

[](#exception-flow)

Use `validate()` (or `validateOrFail()`) to directly get validated data or throw a `ValidationException` when validation fails.

```
use Lukman\Validation\Validator;
use Lukman\Validation\Exception\ValidationException;

$validator = new Validator($data, $rules);

try {
    $validated = $validator->validate(); // or validateOrFail()
} catch (ValidationException $e) {
    $errors = $e->errors(); // MessageBag
    print_r($errors->toArray());
}
```

To validate without throwing exceptions, use the `safe()` helper:

```
$validated = $validator->safe(); // Returns validated fields only, without throwing
```

Rules Formatting
----------------

[](#rules-formatting)

### String Rules

[](#string-rules)

Separate multiple rules with a pipe `|` character. Rule parameters are separated by commas `,`.

```
$rules = [
    'email' => 'required|string|email',
    'age' => 'required|integer|between:18,99',
];
```

### Array Rules

[](#array-rules)

Rules can also be provided as an array, enabling the use of rule objects and closures.

```
$rules = [
    'email' => ['required', 'string', 'email'],
    'status' => [
        'required',
        function (string $attribute, mixed $value, array $data): bool {
            return in_array($value, ['active', 'inactive'], true);
        },
    ],
];
```

Nested Data
-----------

[](#nested-data)

Validate deep nested arrays using dot notation:

```
$data = [
    'user' => [
        'profile' => [
            'name' => 'Lukman',
        ],
    ],
];

$rules = [
    'user.profile.name' => 'required|string|min:2',
];

$validator = new Validator($data, $rules);
$validated = $validator->validate();
// Returns: ['user' => ['profile' => ['name' => 'Lukman']]]
```

Wildcard Validation
-------------------

[](#wildcard-validation)

Validate all elements within an array using the wildcard `*` operator. Error keys will automatically map to the specific indices:

```
$data = [
    'items' => [
        ['qty' => 5],
        ['qty' => 'not-a-number'],
    ],
];

$rules = [
    'items.*.qty' => 'required|integer',
];

$validator = new Validator($data, $rules);
$validator->passes(); // false

$errors = $validator->errors();
echo $errors->first('items.1.qty'); // "The items.1.qty must be an integer."
```

Custom Messages
---------------

[](#custom-messages)

Define custom messages globally per rule or specifically for a field:

```
$messages = [
    'required' => 'The :attribute field is mandatory.',
    'email.required' => 'Please provide your email address.',
    'items.*.qty.integer' => 'Quantity must be a valid number.',
];

$validator = new Validator($data, $rules, $messages);
```

### Placeholders

[](#placeholders)

Custom messages support the following placeholder values:

- `:attribute`: The human-readable name of the validated field.
- `:value`: The value of the field being validated.
- `:min`: Parameter used in `min` or `between` rules.
- `:max`: Parameter used in `max` or `between` rules.
- `:size`: Parameter used in the `size` rule.
- `:other`: Name of the compared field in `same` or `different` rules.

Custom Attributes
-----------------

[](#custom-attributes)

Translate technical field paths into user-friendly names:

```
$attributes = [
    'email' => 'email address',
    'items.*.qty' => 'item quantity',
];

$validator = new Validator($data, $rules, [], $attributes);
```

Extensibility &amp; Custom Rules
--------------------------------

[](#extensibility--custom-rules)

### Custom Rule Objects (RuleInterface)

[](#custom-rule-objects-ruleinterface)

Create a class implementing `RuleInterface`:

```
use Lukman\Validation\RuleInterface;

class UppercaseRule implements RuleInterface
{
    public function passes(string $attribute, mixed $value, array $data): bool
    {
        return is_string($value) && strtoupper($value) === $value;
    }

    public function message(string $attribute): string
    {
        return 'The :attribute must be in uppercase letters.';
    }
}
```

Use it in your rules array:

```
$rules = [
    'code' => ['required', new UppercaseRule()],
];
```

### Closure Rules

[](#closure-rules)

Define quick rules inline using Closures:

```
$rules = [
    'username' => [
        'required',
        function (string $attribute, mixed $value, array $data): bool|string {
            if ($value === 'admin') {
                return 'You cannot choose "admin" as your username.';
            }
            return true; // Return true if valid
        }
    ]
];
```

### Global Factory Extensions

[](#global-factory-extensions)

Register custom rules globally to use them with string rule definitions:

```
use Lukman\Validation\ValidatorFactory;

ValidatorFactory::extend('strong_password', function (string $attribute, mixed $value, array $parameters, array $data): bool {
    return is_string($value) && strlen($value) >= 8 && preg_match('/[A-Z]/', $value);
}, 'The :attribute must be at least 8 characters long and contain an uppercase letter.');

// Now use it like any standard rule string:
$rules = [
    'password' => 'required|strong_password',
];
```

Post-Validation Hooks (after)
-----------------------------

[](#post-validation-hooks-after)

Attach callbacks that execute after standard rule evaluations. This is useful for complex, multi-field, or conditional validation checks:

```
$validator = new Validator($data, $rules);

$validator->after(function (Validator $v) {
    if ($v->validated()['password'] === $v->validated()['username']) {
        $v->errors()->add('password', 'Password cannot be the same as username.');
    }
});
```

Runtime Mutation
----------------

[](#runtime-mutation)

Change the dataset or rule configurations dynamically using setters. Setting new data or rules automatically clears existing errors and resets the validation state:

```
$validator = new Validator($data, $rules);
$validator->passes(); // Runs validation

// Change data and validate again
$validator->setData($newData);
$validator->passes(); // Re-runs validation on new data

// Change rules and validate again
$validator->setRules($newRules);
$validator->passes(); // Re-runs validation on new rules
```

License
-------

[](#license)

This package is open-source software licensed under the [MIT License](LICENSE).

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance95

Actively maintained with recent releases

Popularity16

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity46

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

Unknown

Total

1

Last Release

46d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/64991223?v=4)[Lukman](/maintainers/lukman-ss)[@lukman-ss](https://github.com/lukman-ss)

---

Top Contributors

[![lukman-ss](https://avatars.githubusercontent.com/u/64991223?v=4)](https://github.com/lukman-ss "lukman-ss (5 commits)")

---

Tags

phpvalidatorvalidationstandalone

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

PHPackages © 2026

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