PHPackages                             imediafrance/ammit - 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. imediafrance/ammit

Abandoned → [ammit-php/ammit](/?search=ammit-php%2Fammit)Project[Validation &amp; Sanitization](/categories/validation)

imediafrance/ammit
==================

\[DDD\] Stable framework agnostic Command resolver

v0.9.0(9y ago)37622[7 issues](https://github.com/ammit-php/ammit/issues)MITPHPPHP &gt;=7.0

Since Feb 5Pushed 8y ago6 watchersCompare

[ Source](https://github.com/ammit-php/ammit)[ Packagist](https://packagist.org/packages/imediafrance/ammit)[ RSS](/packages/imediafrance-ammit/feed)WikiDiscussions master Synced today

READMEChangelog (6)Dependencies (5)Versions (8)Used By (0)

[![](https://cloud.githubusercontent.com/assets/2279794/21160379/ef90f812-c184-11e6-99da-add0658f2baf.png)](https://cloud.githubusercontent.com/assets/2279794/21160379/ef90f812-c184-11e6-99da-add0658f2baf.png)

\# Ammit ![PHP7](https://camo.githubusercontent.com/d23ce60b89c28c023d0ca69981ec9afbb17eb08a9cd1b609fd84c15d0732b7ce/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d372d626c75652e737667)![DDD](https://camo.githubusercontent.com/04299b2bdf8875f4bb79f911fe11ecead71cecfe13b6c0d1dd2cbdbd30ac88da/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4444442d446f6d61696e25323044726976656e25323044657369676e2d626c75652e737667)![v1.0.0 beta](https://camo.githubusercontent.com/e3dcee49c93fa4a00298e0b8543866993dd8c7fac04f1580d1ebdf117e507414/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76312e302e302d626574612d6f72616e67652e737667)![v2.0.0 never](https://camo.githubusercontent.com/cd415584482df3c28a7c7ae510813ceb1922a0f6e5cb0c83628576b97f619757/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76322e302e302d6e657665722d7265642e737667)[![SemVer](https://camo.githubusercontent.com/b60510446a33e05651daba8e7f28970ce1cacd42bc995c7ee100f392d3c24b40/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53656d5665722d582e592e5a2d627269676874677265656e2e737667)](http://semver.org/)[![Build Status](https://camo.githubusercontent.com/33167913d78648a2cc8ec24094af1a9e7cdb265ce80b20a8f1119d7cf5df07e2/68747470733a2f2f7472617669732d63692e6f72672f616d6d69742d7068702f616d6d69742e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/ammit-php/ammit)[![Code Quality](https://camo.githubusercontent.com/ec06b0d1c0b096eb780dfe6457066181abac14c430550ae6f2cdd56e72594be1/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f616d6d69742d7068702f616d6d69742f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/ammit-php/ammit)[![Code Coverage](https://camo.githubusercontent.com/d09922db1c23bf1337f0305fbbdb8e1d6f69a750fa559aa68f5df18d97d4d499/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f616d6d69742d7068702f616d6d69742f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/ammit-php/ammit)[![Dependency Status](https://camo.githubusercontent.com/91fc644509aa2c02af4d7c2a33d5ffcd277bddd4941ca1f06f478d814e0a7d92/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d6e6f6e652d677265656e2e737667)](https://www.versioneye.com/user/projects/58a229448516c700164c1e01)

A light, stable and framework agnostic Command resolver library

Currently being Battle Tested (not yet 1.0.0 tagged)
====================================================

[](#currently-being-battle-tested-not-yet-100-tagged)

1. [What the lib does](#what-the-lib-does-)
2. [How to use it ?](#how-to-use-it-)
3. [What the lib does not ?](#what-the-lib-does-not-)
4. [Why ?](#why-)
5. [How does it work ?](#how-does-it-work-)
6. [Pragmatic ?](#pragmatic-)
7. [Want to contribute ?](#want-to-contribute-)
8. [Ammit ?](#ammit-)

A [Command](http://verraes.net/2013/04/decoupling-symfony2-forms-from-entities/) is a simple well named [DTO](http://martinfowler.com/eaaCatalog/dataTransferObject.html) reflecting user **intention**.

Consequently it shall be **immutable**.

[![](/docs/RegisterUserCommand.png)](/docs/RegisterUserCommand.png)

- *RegisterUserCommand*
- *DisableUserCommand*
- *BookCargoCommand*

#### What the lib does ?

[](#what-the-lib-does-)

- It provides a helper to easily **extract** scalar data from a PSR-7 HTTP Request (or a CLI input) in order to instantiate an immutable Command.
- It allows to implement clean Commands (no public field).
- It is designed to be a simple **UI Validation** framework dependency free.
- It is designed to ease segregating UI validation Vs Domain validation concerns

---

[![Simple Spec](/docs/specification-simple.png)](/docs/specification-simple.png)

#### How to use it ?

[](#how-to-use-it-)

`composer require ammit-php/ammit`

Example:

Implement a `RegisterUserCommandResolver` which will map a PSR-7 `ServerRequestInterface` into a `RegisterUserCommand`. Before creating `RegisterUserCommand` it will perform a UI validation.

*RegisterUserController.php*

```
$registerUserCommandResolver = new RegisterUserCommandResolver();
try {
    $command = $registerUserCommandResolver->resolve($request);
} catch (AbstractNormalizableCommandResolverException $e) {
    // Return a JSON error following jsonapi.org's format
    // @see http://jsonapi.org/examples/#error-objects-basics
    return JsonResponse::fromJsonString(
        json_encode(
            $e->normalize()
        ),
        406
    );
}

try {
    $this->userService->registerUser($command);
} catch(DomainException $e) {
   // ...
}
// ...
```

*RegisterUserCommandResolver.php*

```
/**
 * Resolve a PSR-7 Request into a RegisterUserCommand (Data Transfer Object)
 */
class RegisterUserCommandResolver extends AbstractPureCommandResolver
{
    /**
     * @inheritdoc
     */
    public function resolve(ServerRequestInterface $request): RegisterUserCommand
    {
        $commandConstructorValues = $this->resolveRequestAsArray($request);

        // We are using variadic function here (https://wiki.php.net/rfc/variadics)
        return new RegisterUserCommand(...$commandConstructorValues);
    }

    /**
     * @inheritDoc
     */
    protected function validateThenMapAttributes(ServerRequestInterface $request): array
    {
        // $id = $_GET['id']
        $id = $this->queryStringValueValidator->mustBeString(
            $request,
            'id'
        );

        // $firstName = $_POST['firstName']
        $firstName = $this->attributeValueValidator->mustBeString(
            $request,
            'firstName'
        );

        // $lastName = $_POST['lastName']
        $lastName = $this->attributeValueValidator->mustBeString(
            $request,
            'lastName'
        );

        // $email = $_POST['email']
        $email = $this->attributeValueValidator->mustBeString(
            $request,
            'email'
        );

        // Will be injected directly in RegisterUserCommand::__construct(...$args)
        // as variadic function
        $commandConstructorValues = [
            $id,
            $firstName,
            $lastName,
            $email
        ];

        return $commandConstructorValues;
    }
}
```

Use it with Symfony:

Use it with Laravel: TBA

#### Public API

[](#public-api)

##### Pure extending AbstractPureCommandResolver

[](#pure-extending-abstractpurecommandresolver)

   Raw $\_GET $\_POST    $this-&gt;rawValueValidator $this-&gt;queryStringValueValidator $this-&gt;attributeValueValidator   Boolean -&gt;mustBeBoolean(...)   String -&gt;mustBeString(...)   Integer -&gt;mustBeInteger(...)   Float -&gt;mustBeFloat(...)   Array -&gt;mustBeArray(...)   Date -&gt;mustBeDate(...)   DateTime -&gt;mustBeDateTime(...) ##### Pragmatic extending AbstractPragmaticCommandResolver

[](#pragmatic-extending-abstractpragmaticcommandresolver)

   Raw $\_GET $\_POST    $this-&gt;rawValueValidator $this-&gt;queryStringValueValidator $this-&gt;attributeValueValidator   Same as AbstractPureCommandResolver   UUID -&gt;mustBeUuid(...)   Length -&gt;mustHaveLengthBetween(...)   Email -&gt;mustBeEmailAddress(...)   Regex -&gt;mustBeValidAgainstRegex(...) #### What the lib does not ?

[](#what-the-lib-does-not-)

- It is not designed to be a Symfony [Form Component](https://symfony.com/doc/current/components/form.html) replacement.
- It is not designed to create complex validation. It's aim is to validate simple scalar. Yet it still allows "[pragmatic](https://github.com/ammit-php/ammit#pragmatic-)" complex UI validation for prototyping/RAD.
- It is not designed to use PHP reflection. It is only meant to use Command constructor.

#### Why ?

[](#why-)

We were using Symfony [Form Component](https://symfony.com/doc/current/components/form.html) to map and validate HTTP Requests to our Commands.

But it was way too complex and [hacky](https://github.com/webdevilopers/php-ddd/issues/5). And too tempting to put our Domain validation into FormType. Then to "forget" to put it back into our Domain.

Furthermore we wanted to anticipate [Immutable class](https://wiki.php.net/rfc/immutability).

#### How does it work ?

[](#how-does-it-work-)

[![Complete Spec](/docs/specification-complete.png)](/docs/specification-complete.png)

It is using `\Closure` internally in order to be able to catch all `\Exception`. Otherwise it would display only 1 validation issue. And we want to see all validation issues at once like with Forms.

#### Pragmatic ?

[](#pragmatic-)

You may have needs to put some Domain validation in your UI. Sometimes we need to do some Rapid Application Development when prototyping. And to take shortcuts knowing we will have to pay back our technical debt in a near future.

With **Ammit** you would use our `AbstractPragmaticCommandhenResolver` (**Pragmatic**) instead of our `AbstractPureCommandResolver` (**Pure**) helper. It will allow you to use more complex validation like `uuid` validation for example:

```
$email = $attributeValueValidator->mustBeUuid(
    $request,
    'id'
);
```

A validation is missing. You can still inject your own.

#### Want to contribute ?

[](#want-to-contribute-)

Read [UBIQUITOUS\_LANGUAGE\_DICTIONARY.md](UBIQUITOUS_LANGUAGE_DICTIONARY.md)

Init docker container: `docker-compose up -d`

Composer install: `docker-compose run --rm composer install`

Use container: `docker/bin/php -v` (first do `chmod +x docker/bin/php`)

Add Unit Test then: `docker/bin/php bin/atoum`

#### Ammit ?

[](#ammit-)

> Ammit, an ancient egyptian goddess involved in heart weighting. She was devouring souls of human judged to be not pure enough to continue their voyage towards Osiris and immortality.

###  Health Score

23

—

LowBetter than 26% of packages

Maintenance0

Infrequent updates — may be unmaintained

Popularity18

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 94.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 ~17 days

Recently: every ~11 days

Total

6

Last Release

3344d ago

Major Versions

v0.9.0 → v1.0.0-beta2017-03-19

### Community

Maintainers

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

---

Top Contributors

[![gmorel](https://avatars.githubusercontent.com/u/2279794?v=4)](https://github.com/gmorel "gmorel (16 commits)")[![jeremy-hyde](https://avatars.githubusercontent.com/u/22114834?v=4)](https://github.com/jeremy-hyde "jeremy-hyde (1 commits)")

---

Tags

dddformlibrarymappingphppsr7-requestvalidation

### Embed Badge

![Health badge](/badges/imediafrance-ammit/health.svg)

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

###  Alternatives

[aws/aws-sdk-php

AWS SDK for PHP - Use Amazon Web Services in your PHP project

6.2k532.1M2.5k](/packages/aws-aws-sdk-php)[symfony/symfony

The Symfony PHP framework

31.4k86.9M2.2k](/packages/symfony-symfony)[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

7.9k1.1B3.8k](/packages/guzzlehttp-psr7)[neuron-core/neuron-ai

The PHP Agentic Framework.

2.0k496.1k33](/packages/neuron-core-neuron-ai)[aporat/store-receipt-validator

PHP receipt validator for Apple App Store and Amazon Appstore

6513.9M11](/packages/aporat-store-receipt-validator)[laminas/laminas-validator

Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria

15847.1M212](/packages/laminas-laminas-validator)

PHPackages © 2026

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