PHPackages                             antoninmasek/simple-hydrator - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. antoninmasek/simple-hydrator

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

antoninmasek/simple-hydrator
============================

Simple object hydrator

2.0.2(10mo ago)15.8k1MITPHPPHP ^8.2CI passing

Since May 26Pushed 10mo ago1 watchersCompare

[ Source](https://github.com/antoninmasek/simple-hydrator)[ Packagist](https://packagist.org/packages/antoninmasek/simple-hydrator)[ Docs](https://github.com/antoninmasek/simple-hydrator)[ RSS](/packages/antoninmasek-simple-hydrator/feed)WikiDiscussions main Synced 4w ago

READMEChangelog (10)Dependencies (3)Versions (16)Used By (0)

Simple Hydrator
===============

[](#simple-hydrator)

[![Latest Version on Packagist](https://camo.githubusercontent.com/962f5cfdba06d2b6e973371af0a4c3fbee31064ef8fe7a0ecc2a58fa02caedeb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616e746f6e696e6d6173656b2f73696d706c652d6879647261746f722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/antoninmasek/simple-hydrator)[![Tests](https://github.com/antoninmasek/simple-hydrator/actions/workflows/run-tests.yml/badge.svg?branch=main)](https://github.com/antoninmasek/simple-hydrator/actions/workflows/run-tests.yml)[![Total Downloads](https://camo.githubusercontent.com/57c3cdf98edc8cc3ae94d279034e738ff8b543170e9583438035542c2e5af1b4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f616e746f6e696e6d6173656b2f73696d706c652d6879647261746f722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/antoninmasek/simple-hydrator)

This package aims to be an extremely easy-to-use object hydrator. You give it an array and it will try to hydrate your data object. I found myself repeating this logic a few times on different projects, so I decided to package it up. I am well aware, that there are far more superior alternatives, but my aim was to do the implementation as simple as possible.

Also, the main objective for me was, to scratch my own itch. So even though the implementation is now limited and possibly contains some issues, for me, it is currently doing the job just fine. If you, however, find yourself using it too and find an issue, feel free to PR it :)

### TLDR

[](#tldr)

This package helps you create objects from arrays like this:

```
$data = ['name' => 'John', 'age' => 42];

class Human extends \AntoninMasek\SimpleHydrator\DataObject
{
    public string $name;

    public int $age;
}

Human::fromArray($data);
```

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

[](#installation)

You can install the package via composer:

```
composer require antoninmasek/simple-hydrator
```

Usage
-----

[](#usage)

To hydrate your data object you have two options:

### Hydrator::hydrate

[](#hydratorhydrate)

You can use the `Hydrator` as follows:

```
$human = Hydrator::hydrate(Human::class, $data);
```

Advantage of this approach is, that your data object does not have to extend anything. Downside is, that without PHP Doc you won't have autocompletion.

### *YourDataObject*::fromArray

[](#yourdataobjectfromarray)

This way, you can extend your data object with `DataObject` abstract class, which will enable you to call `fromArray`method directly on your data object.

```
$human = Human::fromArray($data);
```

Main advantage is autocompletion as well as better readability. Disadvantage is, that you have to extend your data object. At least the parent. Nested object does not have to extend anything.

### Different keys

[](#different-keys)

In a normal circumstances the package maps object property names 1:1 with input array keys. This might not be always optimal. Either the input array might contain invalid characters for PHP properties, or you just want assign your own names. Let's demonstrate this with an example. Imagine we want to get image dimensions and the input array has the following format:

```
$imageData = [
    "ExifImageWidth" => 4032,
    "ExifImageHeight" => 3024,
]
```

But we want our DTO to look like this:

```
class ImageData
{
    public int $width;
    public int $height;
}
```

The solution to this is to use `Key` attribute and specify the real key value from the source array:

```
use AntoninMasek\SimpleHydrator\Attributes\Key;

class ImageData
{
    #[Key('ExifImageWidth')]
    public int $width;

    #[Key('ExifImageHeight')]
    public int $height;
}
```

And that's it!

### Collections

[](#collections)

If you find yourself in a scenario, where you'd have let's say a `Car` object that has many `Key` objects:

```
$car = [
    'brand' => 'Chevrolet',
    'type'  => 'Camaro',
    'keys'  => [
        [
            'name'      => 'main',
            'is_active' => true,
        ],
        [
            'name'      => 'secondary',
            'is_active' => false,
        ],
    ],
];
```

And you need to cast each of the `keys` to a `Key` object, you may add `#[Collection(Key::class)]` attribute to your data object definition as such:

```
use AntoninMasek\SimpleHydrator\Attributes\Collection;

class Car
{
    public string $type;
    public string $brand;
    public ?ClassThatNeedsCustomCaster $customCaster;

    #[Collection(Key::class)]
    public ?array $keys;
}
```

This ensures correct casting and you will end up with an array of `Key` objects.

#### Your root array is list of objects

[](#your-root-array-is-list-of-objects)

If your source array is a list of objects and you just want to cast it, then instead of the `fromArray` method you may use `collectionFromArray`

### DTO Making

[](#dto-making)

For each of your DTO's properties you can use either a camelCase or snake\_case approach to set their values which ever suites your preference, in the example below we have the propeties `first_name` and `last_name` set on the DTO here.

```
$person = Human::make()
    ->firstName('John')
    ->lastName('Doe')
    ->kids(3);
```

If you prefer to persist autocompletion you may also use `set` method, where the first argument is property name and the second one is the value. So to replicate the example above:

```
$person = Human::make()
    ->set('firstName', 'John')
    ->set('lastName', 'Doe')
    ->set('kids', 3);
```

### Casters

[](#casters)

For cases, where the type of property isn't built in PHP, or it needs a special care than just try to fill properties by name it is possible to write a caster.

#### Caster class

[](#caster-class)

The first way to define a caster is to create a class, that extends `AntoninMasek\SimpleHydrator\Casters\Caster`. You only need to implement the `cast` method which is supplied with `$value` parameter that contains the raw data from the input array, that should be used to hydrate this class.

As an example take a look at simple `DateTime` caster:

```
class DateTimeCaster extends Caster
{
    public function cast(mixed $value): ?DateTime
    {
        if (is_null($value)) {
            return null;
        }

        return new DateTime($value);
    }
}
```

It expects the `$value` to be a string in valid date format. For example `1969-07-20` and returns a `DateTime` object with this date.

#### Anonymous caster

[](#anonymous-caster)

If you don't want to create a caster class you can create anonymous caster by supplying a closure instead of a caster class.

```
Caster::registerCaster(DateTime::class, function ($value) {
    if (is_null($value)) {
        return null;
    }

    return new DateTime($value);
});
```

#### Registering casters

[](#registering-casters)

You can register casters in two ways. First is to specify the mapping between all classes and their respective casters:

```
Caster::setCasters([
    YourObject::class => YourObjectCaster::class,
    YourSecondObject::class => AnotherCaster::class,
]);
```

Or just specify one caster at a time:

```
Caster::registerCaster(YourObject::class, YourObjectCaster::class);
```

To clear all caster you may use:

```
Caster::clearCasters();
```

#### Overwriting default casters

[](#overwriting-default-casters)

If any of the default casters in the package does not suit your needs you can easily overwrite it. All you need to do is register your caster for the specific class. Registered casters have higher priority and default casters in the package are used if no mapping for the specific class is supplied.

Notes
-----

[](#notes)

- Please note, that since version `1.0.1` any invalid characters in array keys are ignored. That means that for the following array `$data = ['service (Appointments)' => ['2022-06-01']]` the `service (Appointments)` key will be set to `serviceAppointments` object property

> Valid characters are the ones, that will pass the following regex: `[^a-zA-Z0-9_]`

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Credits
-------

[](#credits)

- [Antonín Mašek](https://github.com/antoninmasek)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

42

—

FairBetter than 89% of packages

Maintenance55

Moderate activity, may be stable

Popularity20

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 92.9% 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 ~79 days

Recently: every ~167 days

Total

15

Last Release

328d ago

Major Versions

0.5.0 → 1.0.02023-06-26

1.1.3 → 2.0.02023-10-24

PHP version history (2 changes)0.1.0PHP ^8.0|^8.1

0.5.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/8faef5fac979c7f7fa3622af216db9734384499fa3890e62e9f6e97b421b204f?d=identicon)[antoninmasek](/maintainers/antoninmasek)

---

Top Contributors

[![antoninmasek](https://avatars.githubusercontent.com/u/31475951?v=4)](https://github.com/antoninmasek "antoninmasek (39 commits)")[![sweptsquash](https://avatars.githubusercontent.com/u/9886472?v=4)](https://github.com/sweptsquash "sweptsquash (3 commits)")

---

Tags

antoninmaseksimple-hydrator

###  Code Quality

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/antoninmasek-simple-hydrator/health.svg)

```
[![Health](https://phpackages.com/badges/antoninmasek-simple-hydrator/health.svg)](https://phpackages.com/packages/antoninmasek-simple-hydrator)
```

###  Alternatives

[ramsey/devtools

A Composer plugin to aid PHP library and application development.

7134.7k26](/packages/ramsey-devtools)[jimbojsb/workman

PHP process forking &amp; daemonizing library

608.8k](/packages/jimbojsb-workman)

PHPackages © 2026

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