Skip to content

⚡ The best PHP mapper (hydrator/serializer) you've ever seen!

License

Notifications You must be signed in to change notification settings

php-type-language/mapper

Repository files navigation


PHP 8.1+ Latest Stable Version Latest Unstable Version License MIT

The best PHP mapper you've ever seen =)

You can see some examples here:

Full documentation in progress...

Installation

Mapper package is available as Composer repository and can be installed using the following command in a root of your project:

composer require type-lang/mapper

Benchmarks

Results here like this.

Sample: An object that contains a collection of objects, which contains another collection of objects.

ExampleObject{
    name: string,
    items: list<ExampleObject>
}

Denormalization

Denormalization: Transformation from raw payload (array) to concrete object.

subject revs its mem_peak mode rstdev
benchJmsWithAttributes 50 20 4.466mb 32.151μs ±1.70%
benchTypeLangWithDocBlocks 50 20 3.870mb 34.175μs ±1.61%
benchTypeLangWithAttributes 50 20 3.870mb 34.379μs ±1.77%
benchValinorWithPhpStan 50 20 3.870mb 119.750μs ±1.21%
benchSymfonyWithDocBlock 50 20 3.870mb 123.889μs ±1.35%
benchSymfonyWithPhpStan 50 20 3.870mb 126.807μs ±1.94%

Normalization

Normalization: Transformation from object to raw payload (array).

subject revs its mem_peak mode rstdev
benchTypeLangWithDocBlocks 50 20 3.870mb 36.473μs ±1.69%
benchTypeLangWithAttributes 50 20 3.870mb 36.735μs ±1.68%
benchSymfonyWithPhpStan 50 20 3.870mb 37.050μs ±1.20%
benchSymfonyWithDocBlock 50 20 3.870mb 37.125μs ±1.50%
benchValinorWithPhpStan 50 20 3.870mb 38.229μs ±1.38%
benchJmsWithAttributes 50 20 3.870mb 44.614μs ±1.92%

Quick Start

use TypeLang\Mapper\Mapping\MapType;

class ExampleObject
{
    public function __construct(
        #[MapType('list<non-empty-string>')]
        public readonly array $names,
    ) {}
}

$mapper = new \TypeLang\Mapper\Mapper();

$result = $mapper->normalize(
    new ExampleObject(['Example'])
);
// Expected Result:
//
// array:1 [
//   "names" => array:1 [
//     0 => "Example"
//   ]
// ]


$result = $mapper->denormalize([
    'names' => ['first', 'second']
], ExampleObject::class);
// Expected Result:
//
// ExampleObject {#324
//   +names: array:2 [
//     0 => "first"
//     1 => "second"
//   ]
// }


$result = $mapper->denormalize([
    'names' => ['first', 'second', ''],
], ExampleObject::class);
// Expected Result:
//
// InvalidFieldTypeValueException: Passed value of field "names" must be of type
//   list<non-empty-string>, but array(3)["first", "second", ""] given at $.names[2]