PHPackages                             morebec/orkestra-normalization - 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. [Database &amp; ORM](/categories/database)
4. /
5. morebec/orkestra-normalization

ActiveLibrary[Database &amp; ORM](/categories/database)

morebec/orkestra-normalization
==============================

Orkestra Component allowing to easily normalize complex object graphs to arrays of primitives for persistence purposes

v2.5.6(3y ago)1527↓100%6Apache-2.0PHPPHP &gt;=7.4

Since Apr 26Pushed 3y ago1 watchersCompare

[ Source](https://github.com/Morebec/orkestra-normalization)[ Packagist](https://packagist.org/packages/morebec/orkestra-normalization)[ RSS](/packages/morebec-orkestra-normalization/feed)WikiDiscussions 2.x Synced 1mo ago

READMEChangelogDependencies (7)Versions (23)Used By (6)

Normalization
=============

[](#normalization)

The normalization component allows to easily normalize complex object graphs to arrays of primitives for persistence purposes.

Essentially, it makes transforming POPOs into human-readable, platform independent serializable arrays of primitives a breeze.

It can be used to:

- Serialize in any format that supports PHP arrays and primitives.
- Dump objects to an SQL database without the need for an ORM.
- Dump complex object graphs to a document store.
- Load an object in memory from a serialized representation.
- Convert HTTP requests to Typed Objects.

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

[](#installation)

Usage
-----

[](#usage)

Let's take an example of an object graph:

```
class Project
{
    /** @var string */
    private $id;

    /** @var string */
    private $title;

    /** @var string */
    private $description;

    /** @var Task[] */
    private $tasks;

    // ...
}

class Task
{
    /** @var string */
    private $id;

    /** @var string */
    private $name;

    /** @var DateTime */
    private $dueDate;

    /** @var bool */
    private $completed;

    // ...
}
```

Here's how one can normalize an object:

```
use Morebec\Orkestra\Normalization\ObjectNormalizer;$project = new Project('prj123456789', 'A new Project', 'This is our latest project');
$project->addTask(new Task('tsk123456789', 'Deploy to production', $dueDate));

// Normalize
$normalizer = new ObjectNormalizer();
$data = $normalizer->normalize($project);

print_r($data);
// Would print:
[
    'id' => 'prj123456789',
    'title' => 'A new Project',
    'description' => 'This is our latest project',
    'tasks' => [
        [
            'id' => 'tsk123456789',
            'name' => 'Deploy to production',
            'dueDate' => '2021-01-01T10:25:55+00:00',
            'completed' => false
        ]
    ]
];
```

This last representation can easily be serialized to json, xml, yaml or any other format.

### Denormalization

[](#denormalization)

Here's how to convert a normalized object back to an instance of its class:

```
// Would print:
use Morebec\Orkestra\Normalization\ObjectNormalizer;$data = [
    'id' => 'prj123456789',
    'title' => 'A new Project',
    'description' => 'This is our latest project',
    'tasks' => [
        [
            'id' => 'tsk123456789',
            'name' => 'Deploy to production',
            'dueDate' => '2021-01-01T10:25:55+00:00',
            'completed' => false
        ]
    ]
];
$normalizer = new ObjectNormalizer();
$project = $normalizer->denormalize($data, Project::class);
```

> The process of denormalization works using reflection inspecting an object's structure. In order to know what into what type to denormalize a value to, the normalizer checks for `@var`annotations on the object for PHP &lt; 7.4, or the declared type for PHP &gt;= 7.4. Therefore, it is important to correctly declare the @var annotations if using an older version of PHP.

### Custom normalizers/denormalizer.

[](#custom-normalizersdenormalizer)

Depending on the structure of your objects you might want to personalize the way they are (de)normalized. A common example is with value objects wrapping primitives:

```
class Username {

    /** @var string */
    private $value;

    public function __construct(string $value) {
        $this->value = $value;
    }

    public function __toString()
    {
        return $this->value;
    }
}
```

Such object out of the box would be normalized as follows:

```
[
    'value' => 'the_username'
];
```

For such object, and especially when they are part of an object graph, you might want to normalize them to the primitive they wrap for example.

To perform this you need to specify a custom normalizer/denormalizer pair and add it to your normalizer:

```
use Morebec\Orkestra\Normalization\Denormalizer\DenormalizationContextInterface;
use Morebec\Orkestra\Normalization\ObjectNormalizer;
use Morebec\Orkestra\Normalization\Normalizer\ObjectNormalizer\FluentNormalizer;
use Morebec\Orkestra\Normalization\Denormalizer\ObjectDenormalizer\FluentDenormalizer;

$normalizer = new ObjectNormalizer();

$normalizer->addNormalizer(FluentNormalizer::for(Username::class)->asString());
$normalizer->addDenormalizer(FluentDenormalizer::for(Username::class)->as(static function (DenormalizationContextInterface $context) {
    return new Username($context->getValue());
}));
```

The `FluentNormalizer` and `FluentDenormalizer` are the most convenient way to define (De)Normalizers. If you want to have full control over them you can implement the `NormalizerInterface` and `DenormalizerInterface`.

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity17

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity61

Established project with proven stability

 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

Every ~33 days

Recently: every ~58 days

Total

22

Last Release

1134d ago

PHP version history (2 changes)2.0PHP &gt;=7.3

v2.3.3PHP &gt;=7.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/10d7f5561446f2d4df4413803946e9f77175155d241f78bd65c0dd94e6caffc5?d=identicon)[jwillp](/maintainers/jwillp)

---

Top Contributors

[![jwillp](https://avatars.githubusercontent.com/u/5913483?v=4)](https://github.com/jwillp "jwillp (3 commits)")

---

Tags

documentnormalizationorkestraormpersistencephpserialization

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/morebec-orkestra-normalization/health.svg)

```
[![Health](https://phpackages.com/badges/morebec-orkestra-normalization/health.svg)](https://phpackages.com/packages/morebec-orkestra-normalization)
```

###  Alternatives

[doctrine/orm

Object-Relational-Mapper for PHP

10.2k285.3M6.2k](/packages/doctrine-orm)[doctrine/mongodb-odm

PHP Doctrine MongoDB Object Document Mapper (ODM) provides transparent persistence for PHP objects to MongoDB.

1.1k23.3M299](/packages/doctrine-mongodb-odm)[cycle/orm

PHP DataMapper ORM and Data Modelling Engine

1.3k835.4k64](/packages/cycle-orm)[analogue/orm

An intuitive Data Mapper ORM for PHP and Laravel

63547.1k3](/packages/analogue-orm)[ergebnis/factory-bot

Provides a fixture factory for doctrine/orm entities.

81702.8k](/packages/ergebnis-factory-bot)[orbitale/array-fixture

A Doctrine Data Fixture service based on PHP arrays.

1636.7k](/packages/orbitale-array-fixture)

PHPackages © 2026

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