PHPackages                             marwanalsoltany/mighty - 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. [Framework](/categories/framework)
4. /
5. marwanalsoltany/mighty

ActiveLibrary[Framework](/categories/framework)

marwanalsoltany/mighty
======================

The last validation library you will ever need!

v1.2.0(3y ago)591.3k2MITPHPPHP &gt;=8.1

Since Aug 9Pushed 3y ago3 watchersCompare

[ Source](https://github.com/MarwanAlsoltany/mighty)[ Packagist](https://packagist.org/packages/marwanalsoltany/mighty)[ Docs](https://github.com/MarwanAlsoltany/mighty/blob/master/README.md)[ Fund](https://ko-fi.com/marwanalsoltany)[ RSS](/packages/marwanalsoltany-mighty/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (7)Dependencies (5)Versions (9)Used By (0)

Mighty
======

[](#mighty)

 [![](./art/mighty-logo.svg)](./art/mighty-logo.svg)

The last validation library you will ever need!

[![PHP Version](https://camo.githubusercontent.com/013170f7b8c913d7a90c98590e9b257cc03130af93a56e5b942fed4dbae2b1eb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d2533453d382e312d79656c6c6f773f7374796c653d666c6174266c6f676f3d706870)](https://github.com/MarwanAlsoltany/mighty/search?l=php)[![Latest Version on Packagist](https://camo.githubusercontent.com/69f9e0550429201fc5836babb9d0d206e03dcee7ad44d1189a171d2e96304ec2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f4d617277616e416c736f6c74616e792f6d69676874792e7376673f7374796c653d666c6174266c6f676f3d7061636b6167697374)](https://packagist.org/packages/MarwanAlsoltany/mighty)[![Total Downloads](https://camo.githubusercontent.com/c02e59af4d241597b64fed33540f10866b275a431cb0dd001585e3008349bada/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f4d617277616e416c736f6c74616e792f6d69676874792e7376673f7374796c653d666c6174266c6f676f3d7061636b6167697374)](https://packagist.org/packages/MarwanAlsoltany/mighty/stats)[![License](https://camo.githubusercontent.com/8e5bdeb25cec99ef8c5345207c75dcab39dc539399bd321e9f4e73396b581686/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d7265642e7376673f7374796c653d666c6174266c6f676f3d676974687562)](./LICENSE)[![Maintenance](https://camo.githubusercontent.com/068fd45ce0e3bc55bc753945ee21519d011ea319c92d060f0a62eac52e76f54e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d61696e7461696e65642d7965732d6f72616e67652e7376673f7374796c653d666c6174266c6f676f3d676974687562)](https://github.com/MarwanAlsoltany/mighty/graphs/commit-activity)[![Documentation](https://camo.githubusercontent.com/19a3eba2e8ba9373aa86794bb0d3e63a8bd794e4ee34edf1437d4a21231c5463/68747470733a2f2f696d672e736869656c64732e696f2f776562736974652d75702d646f776e2d626c75652d7265642f687474702f4d617277616e416c736f6c74616e792e6769746875622e696f2f6d69676874792f646f63732f6170692e737667)](https://MarwanAlsoltany.github.io/mighty/docs/api)
[![GitHub Continuous Integration](https://github.com/MarwanAlsoltany/mighty/actions/workflows/ci.yml/badge.svg)](https://github.com/MarwanAlsoltany/mighty/actions)[![GitHub Continuous Deployment](https://github.com/MarwanAlsoltany/mighty/actions/workflows/cd.yml/badge.svg)](https://github.com/MarwanAlsoltany/mighty/actions)[![Codecov](https://camo.githubusercontent.com/4921a58546d52e4ae20911f78d0c69789622c40e07b6bba35be358b3bbbf56f0/68747470733a2f2f636f6465636f762e696f2f67682f4d617277616e416c736f6c74616e792f6d69676874792f6272616e63682f6d61737465722f67726170682f62616467652e7376673f746f6b656e3d315a5144504e4b564b44)](https://codecov.io/gh/MarwanAlsoltany/mighty)

[![Open in Visual Studio Code](https://camo.githubusercontent.com/821a60ac3a234e9dfc8569606ae5c68c932b15215af5b0a5e73715e3aae8a78e/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6f676f3d76697375616c73747564696f636f6465266c6162656c3d266d6573736167653d4f70656e253230696e2532305653253230436f6465266c6162656c436f6c6f723d32633263333226636f6c6f723d303037616363266c6f676f436f6c6f723d303037616363)](https://open.vscode.dev/MarwanAlsoltany/mighty)

[![Tweet](https://camo.githubusercontent.com/cb820a0ecc9645168e33b03925d7f14691262ddbaeaf66a0a91697803d0cba2d/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f75726c2f687474702f736869656c64732e696f2e7376673f7374796c653d736f6369616c)](https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2FMarwanAlsoltany%2Fmighty&text=Mighty.%20The%20last%20validation%20library%20you%20will%20ever%20need%21%20%23PHP) [![Star](https://camo.githubusercontent.com/2a85e2c66572c01f7cfed46c5df822ad7205de27f84160046e41b60b736d80a1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f4d617277616e416c736f6c74616e792f6d69676874792e7376673f7374796c653d736f6369616c266c6162656c3d53746172)](https://github.com/MarwanAlsoltany/mighty/stargazers)

Table of Contents[Installation](#installation)
[About Mighty](#about-mighty)
[Quickstart](#quickstart)
[mVEL](#mighty-validation-expression-language)
[Examples](#examples)
[Constraints](#constraints)
[Validations](#validations)
[Documentation](https://marwanalsoltany.github.io/mighty/docs/api)
[Specification](./SPECIFICATION.md)
[Changelog](./CHANGELOG.md)

If you like this project and would like to support its development, giving it a ⭐ would be appreciated!

---

Key Features
------------

[](#key-features)

1. Zero dependencies.
2. Framework agnostic, can be integrated in any codebase.
3. Expressive, intuitive and easy to get along with over **250** built-in validation rules.

[![Mighty Demo](art/mighty-demo.png)](art/mighty-demo.png)

---

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

[](#installation)

```
composer require marwanalsoltany/mighty
```

---

About Mighty
------------

[](#about-mighty)

Validation is a common task in any web application. Data passed to the application via forms —or any type of input for that matter— must always be validated against a set of rules. Mighty can handle in an easy and expressive way.

Mighty is fast, powerful, robust, and easy to use validation library that is just fun to work with, it makes validating any data a breeze. Thanks to the power of the [**Mighty Validation Expression Language (mVEL)**](./SPECIFICATION.md) it is not like anything you've seen before. With its validation approach and over **250** built-in rules there is pretty much nothing that you cannot validate with it, in a very expressive and compact manner. Simply put, Mighty is validation on steroids! It is indeed the last validation library you will ever need.

Mighty provides several different approaches to validate data. It's most common use-case is validating incoming data via HTTP requests, but it of course is not limited to that; Mighty provides also attributes in the form of constraints to easily validate models and/or any kind of objects.

Mighty includes a wide variety of convenient validation rules that you may apply as a single rule or combine them with each other using operators to build up even more complex validations.

Quickstart
----------

[](#quickstart)

To learn about Mighty's powerful validation features, let's cut straight to the point and take a look at some examples:

### General Data Validation

[](#general-data-validation)

Validating form data using the `Validator::class`:

```
use MAKS\Mighty\Validator;

$validator = new Validator();

$validator
    ->setData([
        'name'     => 'John Doe',
        'username' => 'john.doe',
        'password' => 'Super@Secret#123',
        'email'    => 'john@doe.com',
        'hobbies'  => ['coding', 'design', 'sports'],
    ])
    ->setValidations([
        // required&string&between:3,255
        'name'      => $validator->validation()->required()->string()->between(3, 255),
        // required&string&matches:/[a-z0-9._-]/i
        'username'  => $validator->validation()->required()->string()->matches('/[a-z0-9._-]/i'),
        // required&string&min:8
        'password'  => $validator->validation()->required()->string()->min(8),
        // required&email
        'email'     => $validator->validation()->required()->email(),
        // null^(required&array&max:5)
        'hobbies'   => $validator
            ->validation()
            ->null()
            ->xor()
            ->group(fn ($validation) => $validation
                ->array()
                ->max(5)
            ),
        // null|(if:${hobbies.validations.array}&(string&min:3))
        // hobby can be null or a string with at least 3 characters if hobbies is an array
        'hobbies.*' => $validator
            ->validation()
            ->null()
            ->or()
            ->group(fn ($validation) => $validation
                ->if('${hobbies.validations.array}')
                ->open()
                ->string()
                ->min(3)
                ->close()
            ),
    ])
    ->validate();

$result = $validator->isOK(); // boolean result of the overall validation result

$errors = $validator->getErrors(); // an array of results of validations that failed

$results = $validator->getResults(); // an array of results of all validations

$validator->check(); // void or throws an exception with a nicely formatted message of what exactly went wrong
```

### Objects Validation

[](#objects-validation)

Validating the state of an object using `Constraint::class` attributes:

```
use MAKS\Mighty\Validation\Strategy;
use MAKS\Mighty\Validation\Behavior;
use MAKS\Mighty\Validation\Operator;
use MAKS\Mighty\Validation\Constraint;
use MAKS\Mighty\Validation\Constraint as Assert;
use MAKS\Mighty\Validation\Constraint\ValidatableObjectInterface;
use MAKS\Mighty\Validation\Constraint\ValidatableObjectTrait;

class ValidatableObject implements ValidatableObjectInterface
{
    use ValidatableObjectTrait;

    #[Assert\Rule\Equals('CONST')]
    public const CONST = 'CONST';

    #[Assert\Rule\In(['STATIC', 'VAR'])]
    public static $static = 'VAR';

    #[Assert\Rule\StringConstraint]
    #[Assert\Rule\StringCharset('UTF-8')]
    #[Assert\Rule\Between(3, 99)]
    public $default = 'DEFAULT';

    #[Assert\Rule\StringConstraint]
    #[Assert\Rule\StringContains('')]
    #[Assert\Rule\Xml]
    public $xml = '';

    #[Assert\Rule\ArrayConstraint]
    #[Assert\Shape([
        'string' => new Assert\Rule\Str,
        'array'  => new Assert\Rule\Arr,
    ])]
    public $array = [
        'string' => 'value',
        'array'  => [],
    ];

    #[Assert\Rule\ObjectConstraint]
    #[Assert\Rule\ObjectIsInstanceOf(ValidatableObjectInterface::class)]
    #[Assert\Valid(message: 'Not valid')]
    public $object;

    #[Assert\Callback('is_scalar', 'Data is not scalar')]
    #[Constraint('string&min:3', strategy: Strategy::FailLazy, messages: [
        'string' => 'Must be string.',
        'min'    => 'Must be longer than ${@arguments.0}.',
    ])]
    public function getDefault()
    {
        return $this->default;
    }

    #[Assert\Compound([
        new Assert\Rule\Str,
        new Assert\Compound([
            new Assert\Rule\Arr,
            new Assert\Compound([
                new Assert\Rule\Blank,
            ], Operator::Not),
        ], Operator::And),
    ], Operator::Xor, Behavior::Pessimistic, Strategy::FailLazy)]
    public static function getStaticProperty()
    {
        return static::$static;
    }
}

$object = new ValidatableObject();

$result = $object->isValid(); // boolean result of the overall validation result

$results = $object->validate(); // an array of results of all validations

$object->check(); // void or throws an exception with a nicely formatted message of what exactly went wrong
```

An example of the output of validating a validatable object would look like this:

```
// check out the previous snippet see the used constraints

$object = new ValidatableObject();
$object->object = new class implements ValidatableObjectInterface {
    use ValidatableObjectTrait;
    // some properties and their validation constraints ...
};
$object->default = null; // this must be a string

$object->check();

// ValidationFailedException::class
// Data failed to pass the validation.
// (01) The value (null) of the "ValidatableObject->default" property failed to pass the validation [string]. Problem: Value must be a string.
// (02) The value (null) of the "ValidatableObject->default" property failed to pass the validation [string.charset:"UTF-8"]. Problem: Value must be encoded in one of the following charsets: ["UTF-8"].
// (03) The value (null) of the "ValidatableObject->default" property failed to pass the validation [between:3,99]. Problem: Value must be between 3 and 99 or have a value/count/length that is between 3 and 99.
// (04) The return value (null) of the "ValidatableObject->getDefault()" method failed to pass the validation [callback]. Problem: Data is not scalar.
// (05) The return value (null) of the "ValidatableObject->getDefault()" method failed to pass the validation [string&min:3]. Problems: Must be string; Must be longer than 3.
```

Check also [`ValidatableObject`](./Tests/Mocks/ValidatableObject.php) and [`ValidatableObjectChild`](./Tests/Mocks/ValidatableObjectChild.php).

[![■](https://user-images.githubusercontent.com/7969982/182090863-c6bf7159-7056-4a00-bc97-10a5d296c797.png)](https://user-images.githubusercontent.com/7969982/182090863-c6bf7159-7056-4a00-bc97-10a5d296c797.png) **Hint:** *More examples can be found in the [Examples](#examples) section.*

---

Mighty Validation Expression Language
-------------------------------------

[](#mighty-validation-expression-language)

Mighty has the concept of Validation Expression. The Validation Expression in its simplest forms is just a string that describes how Mighty should validate the given data. These strings are based on the [Mighty Validation Expression Language Specification (mVEL)](./SPECIFICATION.md). mVEL is pretty simple, human-readable and easy to cope with. It is a combination of well established concepts and/or specifications like [Boolean Algebra](https://en.wikipedia.org/wiki/Boolean_algebra), [Bitwise Operators](https://en.wikipedia.org/wiki/Bitwise_operation#Bitwise_operators), [JSON](https://en.wikipedia.org/wiki/JSON), and [CSV](https://en.wikipedia.org/wiki/Comma-separated_values).

Therefore, Validation Expression may be defined as a string that contains some rules separated by **Bitwise Operators** which will build an expression that when evaluated using **Boolean Algebra** logic, will result in the final result of the validation. The rules can have arguments, the types of these arguments can be denoted using the same rules of **JSON** types. A rule can also have multiple arguments and the arguments are separated by commas (**CSV**).

For example `required&string&between:2,255|null` is a valid Validation Expression, this expression can be understood as the following:

1. The expression has four rules.
2. The expression contains the rules:
    1. `required` Asserts that the input is present.
    2. `string` Asserts that the input is a string.
    3. `between:2,255` Asserts that the input is a string with a length between 2 and 255.
    4. `null` Asserts that the input is null.
3. The final result is the result of evaluating the expression resulting from the result of each rule glued together using bitwise operators.

The `required&string&between:2,255|null` expression means that the input must be present; **AND** of type string; **AND** between 2 and 255 in length; **OR** null. So it's a nullable string that when is not null must be between 2 and 255 characters long.

Lets say the the input was `"Mighty is Awesome!"`, the result of the expression `required&string&between:2,255|null` against that input would be `1&1&1|0` which will result in `1` which is `true`, if the input was `null` the result would be `0&0&0|1` = `1`, if the input was `X` the result would be `0&0&0|0` = `0`, etc ...

Unlike other validations implementations, the concept of **Boolean Algebra** using **Bitwise Operators**, gives the possibility to build up complex validations that are very readable and compact while keeping the rules to a minimum number, reusing existing logic in reversed or compound manner, and finally keeping the code base as DRY as it can be. The benefits can be summarized in the following points:

1. A rule can be **NOT**ed (using `~`) to do the exact opposite of what it normally does.
2. A complex rule can be the result of **AND**ing (using `&`), **OR**ing (using `|`), or **XOR**ing (using `^`), two or more simple rules.
3. Rules can be grouped together and/or given higher precedence by using parentheses, namely **OPEN** (using `(`) and **CLOSE** (using `)`).
4. A Validation Expression can also have behavior, which is a character the prefixes the Validation Expression string that will affect all rules. Available behaviors are:
    1. **NORMAL**: execute all rules, default behavior (no prefix).
    2. **OPTIMISTIC**: stop executing rules after the first success (`?` prefix).
    3. **PESSIMISTIC**: stop executing rules after the first failure (`!` prefix).
5. Readability can be improved by aliasing some rules or adding rules sets as macros and executing them using the `[macro]` syntax.

Also the concept of **JSON** ensures arguments data-types safety, and the concept of **CSV** makes sure the arguments list has clear parsing rules.

The nicest thing, you don't have to memorize all the rules nor the Validation Expression Language syntax. The [`Validation`](./Validation.php) class is a fluent interface that can be used to build a Validation Expression. It knows about all Mighty available rules and has full IDE-Intellisense support to make it as easy as it gets. For example:

```
use MAKS\Mighty\Validation;

// the validation expression: `required&string&between:2,255|null`
// can be constructed using the Validation::class as follows:
$validation = (new Validation())->required()->string()->between(2, 255)->or()->null(); // AND is the default operator
// or statically:
$validation = Validation::required()->string()->between(2, 255)->or()->null();
```

[![■](https://user-images.githubusercontent.com/7969982/182090858-f98dc83e-da1c-4f14-a538-8ac0a9bc43c3.png)](https://user-images.githubusercontent.com/7969982/182090858-f98dc83e-da1c-4f14-a538-8ac0a9bc43c3.png) **Fact:** *It usually takes more words to describe what a validation expression does than the validation expression itself!*

---

Examples
--------

[](#examples)

Here are some examples of real world scenarios:

### Validating a Single Value

[](#validating-a-single-value)

```
use MAKS\Mighty\Validator;

$result = ($validator = new Validator())
    ->validateOne(
        '123',
        $validator
            ->validation()
            // can be an integer or float or a string that is numeric
            // this example is only for demonstration only,
            // the same result can be achieved using numeric() only
            ->integer()->or()->float()->or()->group(
                fn ($validation) => $validation->string()->and()->numeric()
            )
    )
    ->toArray();

// $result would look something like this:
[
    'value' => '123',
    'result' => true,
    'validations' => [
        'integer' => false,
        'float' => false,
        'string' => true,
        'numeric' => true,
    ],
    'errors' => [],
    'metadata' => [
        'basis' => 'integer|float|(string&numeric)',
        'rules' => 'integer|float|(string&numeric)',
        'expression' => '0|0|(1&1)',
    ],
];

// you can also simply use the static helper Validator::validateData($data, $validation);
```

### Validating Structured Data

[](#validating-structured-data)

```
use MAKS\Mighty\Validator;
use App\Service\HaveIBeenPwnedService as PasswordService;

$validator = new Validator();

$data = [
    'name'       => 'John Doe',
    'age'        => 32,
    'email'      => 'john.doe@domian.tld',
    'username'   => 'john.doe',
    'password'   => 'Secret@123',
    'image'      => '/path/to/image.png',
    'submission' => 'now',
    'consent'    => 'yes',
    'data'       => [
        'nickname' => 'JOE',
        'number'   => 7,
        'hobbies'  => [
            'coding',
            'cooking',
            'reading',
        ]
    ],
];

$validations = [
    'name'           => $validator->validation()->required()->string()->stringCharset(['UTF-8', 'ASCII'])->pessimistic(),
    // or using mVEL => required&string&string.charset:'["UTF-8","ASCII"]'
    'age'            => $validator->validation()->required()->integer()->min(18),
    // or using mVEL => required&integer&min:18
    'email'          => $validator->validation()->required()->email()->macro('gmail'),
    // or using mVEL => required&email&[gmail]
    'username'       => $validator->validation()->required()->username(),
    // or using mVEL => required&username
    'password'       => $validator->validation()->required()->password()->callback(fn ($input) => !PasswordService::isPwned($input)),
    // or using mVEL => required&password (NOTE: callback ist not possible, it requires a Validation::class instance that is bound to the Validator::class instance)
    'image'          => $validator->validation()->null()->xor()->group(fn () => $this->image()->imageDimensions(1920, 1080, '=')->or()->accepted()->or()->assertEquals('${this}', 'granted')->optimistic(),
    // or using mVEL => ?assert:${age.value},18,">="|accepted|assert.equals:${this},"granted"
    'data'           => $validator->validation()->required()->array()->arrayHasKey('nickname'),
    // or using mVEL => required&array&array.hasKey:"nickname"
    'data.*'         => $validator->validation()->scalar()->or()->array()->optimistic(),
    // or using mVEL => ?scalar|array
    'data.nickname'  => $validator->validation()->string()->min(2)->max(32),
    // or using mVEL => string&min:2&max:32
    'data.hobbies.*' => $validator->validation()->ifEq('${data.hobbies.validations.array}', false)->or()->group(fn () => $this->string()->min(3)),
    // or using mVEL => if.eq:${data.hobbies.validations.array},false|(string&min:3)
];

$labels = [
    'name'     => 'Name',
    'age'      => 'Age',
    'email'    => 'E-Mail',
    'password' => 'Password',
    'image'    => 'Image',
    'data'     => 'Data',
    'data.*'   => 'Value of data',
    'consent'  => 'Consent',
];

$messages = [
    '*' => [ // this will be expanded for all fields
        'required' => '${@label} is a required field.',
    ],
    'age' => [
        'min' => '${@label} must be at least ${@arguments.0}.',
    ],
    'username' => [
        'matches' => '${@label} must contain letters, numbers, and the following characters ".-_" only.',
    ],
    'consent' => [
        'assert' => 'You must be at least ${@arguments.1} years old to submit this form.',
    ]
];

$validator
    ->setData($data)
    ->setValidations($validations)
    ->setMessages($messages)
    ->setLabels($labels)
    ->validate();

$results = $validator->getResults();

// $result should look something like this:
[
    // this will actually be a Result object
    // array syntax is used here for demonstration purposes
    'name' => [
        'key' => 'name',
        'value' => 'John Doe',
        'result' => true,
        'validations' => [
            'required' => true,
            'string' => true,
            'string.charset' => true,
        ],
        'errors' => [],
        'metadata' => [
            'basis' => '!required&string&string.charset:["UTF-8","ASCII"]',
            'rules' => 'required&string&string.charset:["UTF-8","ASCII"]',
            'expression' => '1&1&1',
        ],
    ],
    // other validations ...
];

// you can also simply use the static helper Validator::validateData($data, $validations);
```

[![■](https://user-images.githubusercontent.com/7969982/182090863-c6bf7159-7056-4a00-bc97-10a5d296c797.png)](https://user-images.githubusercontent.com/7969982/182090863-c6bf7159-7056-4a00-bc97-10a5d296c797.png) **Hint:** *When providing message overrides to the `Validator::class`, it is advised to use the [`Rule\Validation::class`](./src/Rule/Validation.php) to set array keys. This class contains all Mighty built-in rules names as class constants.*

### Extending the Validator

[](#extending-the-validator)

The validator can be extended in three ways:

- By adding a rule.
- By adding an alias.
- By adding a macro.

```
use MAKS\Mighty\Validator;
use MAKS\Mighty\Rule;

$validator = new Validator();

// adding a new rule
$validator->addRule(
    (new Rule())
        ->name('equals')
        ->arguments(['string'])
        ->callback(fn (string $input, mixed $expected): bool => $input == $expected)
        ->parameters(['@input', '@arguments.0'])
        ->comparison(['@output', '===', true])
        ->example('equals:value')
        ->description('Asserts that the input is equal to the given value.')
);

// adding a new rule alias
$validator->addRuleAlias('eq', 'equals');

// adding a new rules macro
$validator->addRuleMacro('gmail', 'string&email&matches:"/@gmail\.com$/i"');

$results = $validator->validateAll(
    [
        'name'  => 'John',
        'email' => 'john@doe.com',
    ],
    [
        'name'  => 'eq:John',
        'email' => 'required&[gmail]',
    ]
);

// $results should look like this:
[
    // items will actually be a Result object
    // array syntax is used here for demonstration purposes
    'name' => [
        'key' => 'name',
        'value' => 'John',
        'result' => true,
        'validations' => [
            'eq' => true,
        ],
        'errors' => [],
        'metadata' => [
            'basis' => 'eq:John',
            'rules' => 'eq:John',
            'expression' => '1',
        ],
    ],
    'email' => [
        'key' => 'email',
        'value' => 'john@gmail.com',
        'result' => false,
        'validations' => [
            'required' => true,
            'string' => true,
            'email' => true,
            'matches' => false,
        ],,
        'errors' => [],
        'metadata' => [
            'basis' => 'required&[gmail]',
            'rules' => 'required&(string&email&matches:"/@gmail\.com$/i")',
            'expression' => '1&(1&1&0)',
        ],
    ],
];
```

[![■](https://user-images.githubusercontent.com/7969982/182090863-c6bf7159-7056-4a00-bc97-10a5d296c797.png)](https://user-images.githubusercontent.com/7969982/182090863-c6bf7159-7056-4a00-bc97-10a5d296c797.png) **Hint:** *Check out the default [`rules`](./src/Validation/Logic/rules), [`aliases`](./src/Validation/Logic/aliases.php), and [`macros`](./src/Validation/Logic/macros.php) of the [`Validator`](./src/Validator.php) to see more examples.*

---

Constraints
-----------

[](#constraints)

Mighty consists of over 250 rules/attributes that can be used to validate any data or the values of classes, class constants, properties, and methods.

The attributes are split into three main groups:

1. Generic Constraint Attributes
2. Special Constraint Attributes
3. Rule Constraint Attributes

### Generic Constraint Attributes Group

[](#generic-constraint-attributes-group)

The Generic Constraint Attributes are located under the [`MAKS\Mighty\Validation`](./src/Validation) namespace.

This group consists currently of one attribute only; that is the [`Constraint`](./src/Validation/Constraint.php) attribute. This attribute takes a Validation Expression to validate the data it is applied to. It is also the base class for all other attributes.

### Special Constraint Attributes Group

[](#special-constraint-attributes-group)

The Special Constraint Attributes are located under the [`MAKS\Mighty\Validation\Constraint`](./src/Validation/Constraint) namespace.

This group contains attributes that do a specific job that is available only in the context of attributes. It consists of the following attributes:

- [`Rule`](./src/Validation/Constraint/Rule.php): This attribute is used to validate any data using a single validation rule. It is also the base class for all attributes in the Rule Constraint Attributes Group.
- [`Callback`](./src/Validation/Constraint/Callback.php): This attribute is used to validate any data using a callback function.
- [`Valid`](./src/Validation/Constraint/Valid.php): This attribute is used to validate the validity of a validatable object.
- [`Shape`](./src/Validation/Constraint/Shape.php): This attribute is used to validate the shape of an array or object. Note that this is the only attribute that validates a set of values (structured data) rather than a single value.
- [`Compound`](./src/Validation/Constraint/Compound.php): This attribute is used to combine a set of constraints to build up a Validation Expression. The constraints can be combined using any operator, and can also have a behavior. It serves as an object-oriented way to build up a Validation Expression.

[![■](https://user-images.githubusercontent.com/7969982/182090864-09a2573a-59e3-4c82-bf9f-e2b9cd360c27.png)](https://user-images.githubusercontent.com/7969982/182090864-09a2573a-59e3-4c82-bf9f-e2b9cd360c27.png) **Note:** *Note that the constraints that are allowed to be used with the `Shape::class` and `Compound::class` attributes must be an actual instances of the `Constraint::class`, `Rule::class`, or `Compound::class`. The `Callback::class`, `Valid::class`, or `Shape::class` of the **Special Constraint Attributes Group** are NOT allowed. If you have a need for this feature, open an issue and we'll discuss implementing it*

### Rule Constraint Attributes Group

[](#rule-constraint-attributes-group)

The Rule Constraint Attributes are located under the [`MAKS\Mighty\Validation\Constraint\Rule`](./src/Validation/Constraint/Rule) namespace.

This group contains attributes that are based on a single validation rule. It consists of most of the attributes Mighty provides. Refer to the [Validations](#validations) section for the full list.

### Adding a Custom Constraint

[](#adding-a-custom-constraint)

Mighty has a huge list of built-in constraints, it's really rare that you will need anything other than what Mighty provides. Nonetheless, sometimes the need arises for a custom constraint, the is how you can achieve that:

```
