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

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]

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>
}

The results are sorted by mode time.

Denormalization

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

benchmark memory min max mode rstdev
TypeLangAttributesBench 1.444mb 141.800μs 156.050μs 145.760μs ±2.13%
JMSAttributesBench 1.429mb 144.400μs 157.100μs 146.736μs ±2.12%
TypeLangDocBlockBench 1.642mb 144.800μs 153.850μs 148.059μs ±1.29%
ValinorBench 1.344mb 217.550μs 229.150μs 220.319μs ±1.41%
SymfonyDocBlockBench 2.163mb 495.350μs 507.950μs 499.492μs ±0.72%
SymfonyPHPStanBench 1.426mb 506.650μs 544.500μs 510.798μs ±1.53%

Denormalization + Cache

benchmark memory min max mode rstdev
TypeLangDocBlockBench 1.544mb 113.250μs 125.350μs 115.831μs ±2.64%
JMSAttributesBench 1.429mb 125.850μs 148.750μs 128.718μs ±3.68%
TypeLangAttributesBench 1.436mb 170.100μs 182.200μs 173.155μs ±1.70%
ValinorBench 1.257mb 341.000μs 374.450μs 346.891μs ±1.94%
SymfonyPHPStanBench 1.370mb 583.600μs 609.050μs 590.473μs ±0.88%
SymfonyDocBlockBench 2.163mb 644.350μs 686.550μs 651.617μs ±1.32%

Normalization

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

benchmark memory min max mode rstdev
JMSAttributesBench 1.476mb 93.550μs 125.100μs 112.011μs ±9.21%
TypeLangDocBlockBench 1.643mb 110.650μs 133.000μs 112.881μs ±4.25%
SymfonyPHPStanBench 1.370mb 112.850μs 121.850μs 115.140μs ±1.89%
TypeLangAttributesBench 1.444mb 117.300μs 127.250μs 120.649μs ±2.43%
ValinorBench 1.251mb 127.300μs 135.350μs 129.379μs ±1.72%
SymfonyDocBlockBench 2.163mb 153.000μs 161.800μs 155.170μs ±1.39%

Normalization + Cache

benchmark memory min max mode rstdev
TypeLangAttributesBench 1.447mb 65.850μs 94.650μs 91.945μs ±6.51%
TypeLangDocBlockBench 1.544mb 91.950μs 97.250μs 93.070μs ±1.49%
JMSAttributesBench 1.429mb 88.150μs 105.600μs 100.956μs ±3.31%
SymfonyPHPStanBench 1.370mb 136.050μs 147.900μs 138.879μs ±1.96%
ValinorBench 1.256mb 114.450μs 161.600μs 152.558μs ±5.88%
SymfonyDocBlockBench 2.163mb 164.300μs 221.300μs 212.265μs ±5.18%