PHPackages                             hanneskod/clean - 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. hanneskod/clean

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

hanneskod/clean
===============

A clean (as in simple) data cleaner (as in validation tool)

3.0.0(6y ago)21.4k11WTFPLPHPPHP &gt;=7.4

Since Dec 31Pushed 5y ago1 watchersCompare

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

READMEChangelogDependencies (1)Versions (5)Used By (1)

hanneskod/clean
===============

[](#hanneskodclean)

[![Packagist Version](https://camo.githubusercontent.com/90c596685dea07eb031c94d7ad6644eea33f2bd1c485628588feecf02f6326c8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f68616e6e65736b6f642f636c65616e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/hanneskod/clean)[![Build Status](https://camo.githubusercontent.com/8d145173e20790569fe369e38dc79d2ad447619e5729c345e9ee33db2ba57136/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f68616e6e65736b6f642f636c65616e2f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/hanneskod/clean)[![Quality Score](https://camo.githubusercontent.com/c11b5d1fe10f43d31a318063af05e1470c7bf9ab384ab5c41bda7dafea9dcfdc/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f68616e6e65736b6f642f636c65616e2e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/hanneskod/clean)

A clean (as in simple) data cleaner (as in validation tool)

Why?
----

[](#why)

Sometimes it's necessary to perform complex input validation, and a number of tools exist for this purpose (think Respect\\Validation). At other times (arguably most times) built in php functions such as the ctype-family and regular expressions are simply good enough. At these times pulling in a heavy validation library to perform basic tasks can be unnecessarily complex.

Clean acts as a thin wrapper around callables and native php functions, *in less than 100 logical lines of code*, and allows you to filter and validate user input through a simple and compact fluent interface.

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

[](#installation)

```
composer require hanneskod/clean
```

Clean requires php 7.4 or later and has no userland dependencies.

Usage
-----

[](#usage)

Basic usage consists of grouping a set of [Rules](src/Rule.php) in an [ArrayValidator](src/ArrayValidator.php).

```
use hanneskod\clean\ArrayValidator;
use hanneskod\clean\Rule;

$validator = new ArrayValidator([
    'foo' => (new Rule)->match('ctype_digit'),
    'bar' => (new Rule)->match('ctype_alpha'),
]);

$tainted = [
    'foo' => 'not-valid only digits allowed',
    'bar' => 'valid'
];

try {
    $validator->validate($tainted);
} catch (Exception $e) {
    echo $e->getMessage();
}
```

### Defining rules

[](#defining-rules)

Rules are defined using the `pre()`, `match()` and `post()` methods.

1. `pre()` takes any number of `callable` arguments to act as pre-match filters. Filters take an argument and return it in it's filtered state.
2. `post()` takes any number of `callable` arguments to act as post-match filters. Filters take an argument and return it in it's filtered state.
3. `match()` takes any number of `callable` arguments to act as validators. The callable should take an argument and return true if the argument is valid and false if it is not.

A rule definition might look like this:

```
use hanneskod\clean\Rule;

$rule = (new Rule)->pre('trim')->match('ctype_alpha')->post('strtoupper');

// outputs FOOBAR
echo $rule->validate('   foobar   ');
```

### Using the regexp matcher

[](#using-the-regexp-matcher)

The `Rule` validator comes with one special case matcher: `regexp()` to match string input against a posix style regular expression (`preg_match()`).

```
use hanneskod\clean\Rule;

$rule = (new Rule)->regexp('/A/');

// outputs ABC
echo $rule->validate('ABC');
```

### Making input optional

[](#making-input-optional)

Rules may define a default value using the `def()` method. The default value is used as a replacement for `null`. This effectively makes the field optional in an ArrayValidator setting.

```
use hanneskod\clean\ArrayValidator;
use hanneskod\clean\Rule;

$validator = new ArrayValidator([
    'key' => (new Rule)->def('baz')
]);

$data = $validator->validate([]);

// outputs baz
echo $data['key'];
```

### Specifying custom exception messages

[](#specifying-custom-exception-messages)

When validation fails an exception is thrown with a generic message describing the error. Each rule may define a custom exception message using the `msg()`method to fine tune this behaviour.

```
use hanneskod\clean\Rule;

$rule = (new Rule)->msg('Expecting numerical input')->match('ctype_digit');

try {
    $rule->validate('foo');
} catch (Exception $e) {
    // outputs Expecting numerical input
    echo $e->getMessage();
}
```

### Ignoring unknown input items

[](#ignoring-unknown-input-items)

By default unkown intput items triggers exceptions.

```
use hanneskod\clean\ArrayValidator;

$validator = new ArrayValidator([]);

// throws a clean\Exception as key is not present in validator
$validator->validate(['this-key-is-not-definied' => '']);
```

Use `ignoreUnknown()` to switch this functionality off.

```
use hanneskod\clean\ArrayValidator;

$validator = (new ArrayValidator)->ignoreUnknown();

$clean = $validator->validate(['this-key-is-not-definied' => 'foobar']);

// outputs empty
echo empty($clean) ? 'empty' : 'not empty';
```

### Nesting validators

[](#nesting-validators)

ArrayValidators can be nested as follows:

```
use hanneskod\clean\ArrayValidator;
use hanneskod\clean\Rule;

$validator = new ArrayValidator([
    'nested' => new ArrayValidator([
        'foo' => new Rule
    ])
]);

$tainted = [
    'nested' => [
        'foo' => 'bar'
    ]
];

$clean = $validator->validate($tainted);

//outputs bar
echo $clean['nested']['foo'];
```

### Inspecting validation results using applyTo()

[](#inspecting-validation-results-using-applyto)

The `validate()` method throws an exception as soon as a match fails. This may of course not always be what you want. You can inspect the validation result directly by using the `applyTo()` method instead.

```
use hanneskod\clean\Rule;

$rule = (new Rule)->match('ctype_digit');

$result = $rule->applyTo('12345');

$result->isValid() == true;

// outputs 12345
echo $result->getValidData();
```

### Catching all of the failures

[](#catching-all-of-the-failures)

Individual errors can be accessed using the result object.

```
use hanneskod\clean\ArrayValidator;
use hanneskod\clean\Rule;

$validator = new ArrayValidator([
    '1' => (new Rule)->match('ctype_digit')->msg('failure 1'),
    '2' => (new Rule)->match('ctype_digit')->msg('failure 2'),
]);

// Both 1 and 2 will fail as they are not numerical
$result = $validator->applyTo(['1' => '', '2' => '']);

//outputs failure 1failure 2
foreach ($result->getErrors() as $errorMsg) {
    echo $errorMsg;
}
```

### Identifying a failing rule

[](#identifying-a-failing-rule)

```
use hanneskod\clean\ArrayValidator;
use hanneskod\clean\Rule;

$validator = new ArrayValidator([
    'foo' => (new Rule)->match('ctype_digit'),
    'bar' => (new Rule)->match('ctype_digit'),
]);

$result = $validator->applyTo([
    'foo' => 'not-valid',
    'bar' => '12345'
]);

// outputs foo
echo implode(array_keys($result->getErrors()));
```

### Implementing custom validators

[](#implementing-custom-validators)

```
use hanneskod\clean\AbstractValidator;
use hanneskod\clean\Rule;
use hanneskod\clean\ValidatorInterface;

class NumberRule extends AbstractValidator
{
    protected function create(): ValidatorInterface
    {
        return (new Rule)->match('ctype_digit');
    }
}

// Outputs 1234
echo (new NumberRule)->validate('1234');
```

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity20

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity66

Established project with proven stability

 Bus Factor1

Top contributor holds 97.3% 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 ~487 days

Total

4

Last Release

2321d ago

Major Versions

1.0.0 → 2.0.02017-10-15

2.0.1 → 3.0.02020-01-01

PHP version history (3 changes)1.0.0PHP &gt;=5.4

2.0.0PHP ^7.0

3.0.0PHP &gt;=7.4

### Community

Maintainers

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

---

Top Contributors

[![hanneskod](https://avatars.githubusercontent.com/u/1369274?v=4)](https://github.com/hanneskod "hanneskod (36 commits)")[![peter279k](https://avatars.githubusercontent.com/u/9021747?v=4)](https://github.com/peter279k "peter279k (1 commits)")

---

Tags

validatorvalidationinput-validation

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/hanneskod-clean/health.svg)

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

###  Alternatives

[respect/validation

The most awesome validation engine ever created for PHP

5.9k37.4M383](/packages/respect-validation)[opis/json-schema

Json Schema Validator for PHP

64236.9M185](/packages/opis-json-schema)[vlucas/valitron

Simple, elegant, stand-alone validation library with NO dependencies

1.6k4.4M128](/packages/vlucas-valitron)[intervention/validation

Additional validation rules for the Laravel framework

6826.7M8](/packages/intervention-validation)[proengsoft/laravel-jsvalidation

Validate forms transparently with Javascript reusing your Laravel Validation Rules, Messages, and FormRequest

1.1k2.3M49](/packages/proengsoft-laravel-jsvalidation)[wixel/gump

A fast, extensible &amp; stand-alone PHP input validation class that allows you to validate any data.

1.2k1.3M29](/packages/wixel-gump)

PHPackages © 2026

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