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

Folders and files

NameName
Last commit message
Last commit date
Jan 11, 2025
Feb 4, 2025
Feb 5, 2025
Feb 4, 2025
Feb 5, 2025
Feb 5, 2025
Jun 29, 2024
Oct 27, 2024
Oct 7, 2024
Oct 11, 2024
Jun 29, 2024
Feb 4, 2025
Nov 18, 2024
Jan 14, 2025
Jan 10, 2025
Oct 29, 2024

Repository files navigation


PHP 8.1+ Latest Stable Version Latest Unstable Version License MIT MetaStorm

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%