PHPackages                             mizmoz/validate - 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. mizmoz/validate

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

mizmoz/validate
===============

Validation inspired by React Prop Types

1.0.1(1y ago)0393[1 PRs](https://github.com/mizmoz/validate/pulls)MITPHPPHP &gt;=8.3CI passing

Since Aug 31Pushed 3mo ago1 watchersCompare

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

READMEChangelog (5)Dependencies (5)Versions (32)Used By (0)

[Mizmoz](https://www.mizmoz.com) / validate
===========================================

[](#mizmoz--validate)

Validation for PHP 7 that tries to suck less.

We've used a lot of different validation libraries over time and I've yet to be truly happy with any of them.

The main aim for this is to create a validator that can handle complex items, resolve them and also create nice descriptions of themselves. The dream is to create a validator that can handle REST API data, send useful error messages to the user and also a nice description of the endpoint. This will be the face of the Mizmoz API.

Table of Contents
-----------------

[](#table-of-contents)

- [Getting started](#getting-started)
    - [Composer installation](#composer-installation)
    - [Keeping the resources up to date](#keeping-the-resources-up-to-date)
    - [Basic validation](#basic-validation)
    - [Testing](#testing)
- [Validators](#validators)
    - [`IsArray`](#isarray)
    - [`IsArrayOf`](#isarrayof)
    - [`IsArrayOfShape`](#isarrayofshape)
    - [`IsArrayOfType`](#isarrayoftype)
    - [`IsBoolean`](#isboolean)
    - [`IsDate`](#isdate)
    - [`IsEmail`](#isemail)
    - [`IsEmailDisposable`](#isemaildisposable)
    - [`IsFilter`](#isfilter)
    - [`IsInteger`](#isinteger)
    - [`IsNumeric`](#isnumeric)
    - [`IsObject`](#isobject)
    - [`IsOneOf`](#isoneof)
    - [`IsOneOfType`](#isoneoftype)
    - [`IsReCaptcha`](#isrecaptcha)
    - [`IsRequired`](#isrequired)
    - [`IsSame`](#issame)
    - [`IsShape`](#isshape)
    - [`IsString`](#isstring)

Getting started
===============

[](#getting-started)

Composer installation
---------------------

[](#composer-installation)

It's probably worth pointing out the API is really new and very likely to change.

```
composer require mizmoz/validate

```

Keeping the resources up to date
--------------------------------

[](#keeping-the-resources-up-to-date)

If you‘re using the IsEmailDisposable validator you‘ll want to make sure you‘re using an up to date list of disposable email host names.

Best practice is you create a cron job that executes the update below.

```
php bin/mizmoz update

```

See the resources folder for an example cron file that should be placed in /etc/cron.d.

Basic validation
----------------

[](#basic-validation)

```
Validate::isString()->validate('Hello there!'); // true

Validate::isObject()->validate(new DateTime); // true

Validate::isArray()->validate([]); // true
Validate::isArray()->validate(new ObjectWithToArray); // true

Validate::isOneOf(['on', 'off'])->validate('on'); // true
Validate::isOneOf(['on', 'off'])->validate('oops'); // false

// Validate a value and return it's object
$result = Validate::isObjectOfType(DateTime::class)->validate('2016-01-01 00:00:00');
$result->isValid(); // true
$result->getValue(); // DateTime 2016-01-01 00:00:00
```

### Resolving a validator to a new value

[](#resolving-a-validator-to-a-new-value)

```
$result = Validate::isSame('me')
    ->toValue(\User::current()->userId)
    ->validate($userId);

// get the user id
$userId = $result->getValue();
```

### More complex and useful examples

[](#more-complex-and-useful-examples)

```
// Validate a set of items
$result = Validate::set([
    'name' => Validate::isString()
        ->setDescription('Subscriber name')
        ->isRequired(),
    'email' => Validate::isEmail()
        ->isRequired(),
    'sendNewsletter' => Validate::isBoolean()
        ->setDescription('Subscribe the email address to the newsletter?')
        ->setDefault(false)
])->validate($_POST);

// Get the sanitised data as an array.
$values = $result->getValue();
```

### Validate ACL

[](#validate-acl)

Whilst there are no validators for ACL (they might come later). There are exceptions that can be returned or thrown in your application. This way you can use a standard set of Exceptions to handle ACL failures. For example we use validation on our API and will catch the AclException to display an error message.

```
// Add custom validator
ValidateFactory::setHelper('aclOwner', function () {
    // add your custom validator
    return new IsOwner();
});

Validate::aclAuthenticated(\User::current())->validate(\User::get(1));
```

Testing
=======

[](#testing)

Any validator or resolver can be mocked using the `ValidatorFactory::mock()` method.

The mocking is pretty simple and just allows for the return Result object to be set by calling methods on the mock object.

```
# Setup the Mock of isString
$mock = ValidatorFactory::mock('isString')
    ->valid(false)
    ->value('fail-value')
    ->message('boo');

Validator::isString()->validate('hello')->isValid(); // false as we've overriden the result

# Reset the container
ValidatorFactory::unMock('isString');

# ... or using the original mock
$mock->unMock();

# You can also make a mock go away after it's called by adding `once()` when setting it up
ValidatorFactory::mock('isString')
    // ... extra setup
    ->once();
```

Getting the parameters passed to the Mocked object

```
# return an array with the param names and the called method either __constructor, validate or resolve
$mock->getCallArguments();
```

Validators
==========

[](#validators)

IsArray
-------

[](#isarray)

Check the value is an array

```
(new IsArray())
    ->validate([1, 2, 3]); // true
```

IsArrayOf
---------

[](#isarrayof)

Check the array contains only the provided values. Useful for checking enums that are allowed multiple values. For only 1 value set [IsOneOf](#isoneof)

```
$validate = (new IsArrayOf(['yes', 'no', 'maybe']));
$validate->validate(['yes']); // pass
$validate->validate(['no']); // pass
$validate->validate(['yes', 'no']); // pass
$validate->validate(['definitely']); // fail
```

IsArrayOfShape
--------------

[](#isarrayofshape)

Same as [IsShape](#isshape) except the $value must be an array.

IsArrayOfType
-------------

[](#isarrayoftype)

Check the array contains only items of the particular type

Checking against a single type

```
$validate = (new IsArrayOfType(
    new IsString()
));

$validate->validate(['Hello']); // pass
$validate->validate([1, 'World']); // fail
```

Checking against multiple types

```
$validate = (new IsArrayOfType([
    new IsString(),
    new IsInteger(),
]));

$validate->validate(['Hello']); // pass
$validate->validate([1, 'World']); // pass
```

IsBoolean
---------

[](#isboolean)

Check the value is boolean-ish, that is 1, '1', true, 'true' &amp; 0, '0', false, 'false'.

```
(new IsBoolean())
    ->validate(true); // true
```

IsDate
------

[](#isdate)

Check the value is a valid date in the format provided.

`$options`

- `string format` - the date format the value is expected to be in
- `bool setValueToDateTime` - set the value from the result to the value when the date is valid.
- `bool strict` - using strict will force empty strings to fail

```
(new IsDate())
    ->validate('2016-01-01'); // true

(new IsDate(['format' => 'd/m/Y']))
    ->validate('01/01/2016'); // true
```

### IsEmailDisposable

[](#isemaildisposable)

Check if the value is a disposable email address like guerillamail.com etc

```
(new IsEmailDisposable())
    ->validate('bob@guerillamail.com'); // true
```

### IsEmail

[](#isemail)

Check if the value is a valid email address

```
(new IsEmail())
    ->validate('support@mizmoz.com'); // true
```

Don‘t allow disposable email addreses

```
(new IsEmail(['allowDisposable' => false]))
```

### IsFilter

[](#isfilter)

The filter is a pretty cool helper for parsing strings for filtering.

#### Basic hash tags with example usage

[](#basic-hash-tags-with-example-usage)

We use the filter to map to column names for things like statuses etc. Only `@tag` &amp; `#tag` are supported anything else will be returned in the filter key as plain text

```
$validate = new IsFilter([
    '#active|#deleted' => 'userStatus'
]);

$result = $validate->validate('#deleted')->getValue(); // returns ['userStatus' => ['delete'], 'filter' => '']

$model = User::create();
foreach ($result as $column => $value) {
    // we have some magic attached to our models for filtering also but you get the idea of how this can be used ;)
    $model->where($column, $value);
}
$model->fetch();
```

Special `:isInteger` tagging

```
$validate = new IsFilter([
    '@:isInteger' => 'userId'
]);

$result = $validate->validate('@123 @456')->getValue(); // returns returns ['userId' => [123, 456], 'filter' => '']
```

The filter value has any tags removed

```
$validate = new IsFilter([
    '#subscribed' => 'userStatus'
]);

$result = $validate->validate('Bob')->getValue(); // returns ['filter' => 'Bob']

// or with tags

$result = $validate->validate('Bob #subscribed')->getValue(); // returns ['userStatus' => ['subscribed'], 'filter' => 'Bob']
```

Default tags when no tags are present using the \*

```
// active is marked as the default
$validate = new IsFilter([
    '#active*|#inactive' => 'status'
]);

$validate->validate('')->getValue(); // returns ['status' => ['active']]

// Or with a filter
$validate->validate('Bob')->getValue(); // returns ['status' => ['active'], 'filter' => 'Bob']
```

Defaults are for the defined group so you can have other tags without defaults

```
// active is marked as the default
$validate = new IsFilter([
    '#active*|#inactive' => 'status',
    '#admin|#user' => 'role',
]);

$validate->validate('')->getValue(); // returns ['status' => ['active']]

// Or with a tag
$validate->validate('#admin')->getValue(); // returns ['status' => ['active'], 'role' => ['admin']]
```

IsInteger
---------

[](#isinteger)

Check the value is an integer

`bool $strict` - set to strict to only allow integers and not number strings or floats.

```
(new IsInteger())
    ->validate(1); // valid
```

IsNumeric
---------

[](#isnumeric)

Check the value is a number

```
(new IsNumeric())
    ->validate(1); // valid

(new IsNumeric())
    ->validate('100'); // valid
```

### IsObject

[](#isobject)

### IsOneOf

[](#isoneof)

### IsOneOfType

[](#isoneoftype)

### IsReCaptcha

[](#isrecaptcha)

Validate a reCAPTCHA response

```
(new IsReCaptcha($secret))
    ->validate($response);
```

### IsRequired

[](#isrequired)

### IsSame

[](#issame)

### IsShape

[](#isshape)

Check the value is a particular shape, sometimes is easier to explain with an example...

```
(new IsShape([
    'name' => new IsString(),
    'age' => new IsInteger(),
]))->validate([
    'name' => 'Bob',
    'age' => 45,
]); // valid
```

Shapes can be nested to validate shapes of shapes.

Using the `Validate::set()` provides a helper to return nice descriptions of the shape.

```
$validate = Validate::set([
    'name' => Validate::isString()
        ->setDescription('Full name')
        ->isRequired(),
]);

// return an array describing the set / shape.
$validate->getDescription();
```

### IsString

[](#isstring)

Check the value is a string

```
(new IsString)
    ->validate('Hello world'); // valid
```

Road map
--------

[](#road-map)

On the todo list
----------------

[](#on-the-todo-list)

- Formalise the API
- Optional descriptions in OpenAPI format:
- Create validators as ReactJS components. Parse the description from Chain to form components.
- Add docs for all remaining validators... there are quite a few more than listed here so be sure to have a look in the src/Validator directory.
- Add more validators!

#### Tasks

[](#tasks)

- Create description for isOneOfType

### General

[](#general)

Allow positive or negative matching. Possibly like this:

```
// Positive match
Validate::is()->email();

// Negative match
Validate::not()->email();
```

### Validators

[](#validators-1)

#### IsPassword

[](#ispassword)

Check a string matches the requirements for the password.

- Minimum length
- Uppercase characters
- Lowercase characters
- Special characters
- Numbers

### Resolvers

[](#resolvers)

#### ToHash

[](#tohash)

Create a hash of the given data with various techniques. MD5, SHA1, password\_hash etc.

### Generate API releases

[](#generate-api-releases)

At Mizmoz we already use the validator chain to generate our API schema in JSON.

The next step would be to create new versions or releases by comparing the new and old API endpoints. This would allow us to create discrete versions for each change and also help with documentation by highlighting each of the changes. We could even go further and highlight breaking changes to the API when defaults etc are changed.

###  Health Score

47

—

FairBetter than 94% of packages

Maintenance61

Regular maintenance activity

Popularity12

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity89

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 97.1% 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 ~101 days

Recently: every ~597 days

Total

30

Last Release

590d ago

Major Versions

0.12.0 → 1.0.12024-09-27

PHP version history (2 changes)0.7.0PHP &gt;=7.0

0.12.0PHP &gt;=8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/37a90e0c6130970a2e26b9ed1ed93a0a95588d7f07a4c166067aec064fd82d4b?d=identicon)[ianchadwick](/maintainers/ianchadwick)

---

Top Contributors

[![ianchadwick](https://avatars.githubusercontent.com/u/733223?v=4)](https://github.com/ianchadwick "ianchadwick (33 commits)")[![ichadwick](https://avatars.githubusercontent.com/u/68679536?v=4)](https://github.com/ichadwick "ichadwick (1 commits)")

---

Tags

filtervalidation

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/mizmoz-validate/health.svg)

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

###  Alternatives

[aporat/store-receipt-validator

PHP receipt validator for Apple App Store and Amazon Appstore

6503.9M9](/packages/aporat-store-receipt-validator)[drupal/core

Drupal is an open source content management platform powering millions of websites and applications.

19462.3M1.3k](/packages/drupal-core)[robertogallea/laravel-codicefiscale

Codice fiscale validation for php/laravel

58151.6k1](/packages/robertogallea-laravel-codicefiscale)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

7310.3k29](/packages/open-dxp-opendxp)[speelpenning/laravel-postcode-nl

A Laravel client using the Postcode.eu REST API for Dutch address verification.

1221.1k](/packages/speelpenning-laravel-postcode-nl)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)

PHPackages © 2026

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