• Stars
    star
    727
  • Rank 62,329 (Top 2 %)
  • Language
    PHP
  • License
    MIT License
  • Created over 11 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🚄 Fast Generated Object Hydrator for PHP

Generated Hydrator

GeneratedHydrator is a library about high performance transition of data from arrays to objects and from objects to arrays.

Tests Releases Downloads
Mutation testing badge Type Coverage Latest Stable Version Total Downloads

What does this thing do?

A hydrator is an object capable of extracting data from other objects, or filling them with data.

A hydrator performs following operations:

  • Convert Object to array
  • Put data from an array into an Object

GeneratedHydrator uses proxying to instantiate very fast hydrators, since this will allow access to protected properties of the object to be handled by the hydrator.

Also, a hydrator of GeneratedHydrator implements Laminas\Hydrator\HydratorInterface.

Installation

To install GeneratedHydrator, install Composer and issue the following command:

$ composer require ocramius/generated-hydrator

Usage

Here's an example of how you can create and use a hydrator created by GeneratedHydrator:

<?php

use GeneratedHydrator\Configuration;

require_once __DIR__ . '/vendor/autoload.php';

class Example
{
    public    $foo = 1;
    protected $bar = 2;
    protected $baz = 3;
}

$config        = new Configuration('Example');
$hydratorClass = $config->createFactory()->getHydratorClass();
$hydrator      = new $hydratorClass();
$object        = new Example();

var_dump($hydrator->extract($object)); // ['foo' => 1, 'bar' => 2, 'baz' => 3]
$hydrator->hydrate(
    ['foo' => 4, 'bar' => 5, 'baz' => 6],
    $object
);
var_dump($hydrator->extract($object)); // ['foo' => 4, 'bar' => 5, 'baz' => 6]

Performance comparison

A hydrator generated by GeneratedHydrator is very, very, very fast. Here's the performance of the various hydrators of Laminas\Hydrator compared to a hydrator built by GeneratedHydrator:

<?php
require_once __DIR__ . '/vendor/autoload.php';

$iterations = 10000;

class Example
{
    public $foo;
    public $bar;
    public $baz;
    public function setFoo($foo) { $this->foo = $foo; }
    public function setBar($bar) { $this->bar = $bar; }
    public function setBaz($baz) { $this->baz = $baz; }
    public function getFoo() { return $this->foo; }
    public function getBar() { return $this->bar; }
    public function getBaz() { return $this->baz; }
    public function exchangeArray($data) {
        $this->foo = $data['foo']; $this->bar = $data['bar']; $this->baz = $data['baz'];
    }
    public function getArrayCopy() {
        return array('foo' => $this->foo, 'bar' => $this->bar, 'baz' => $this->baz);
    }
}

$object        = new Example();
$data          = array('foo' => 1, 'bar' => 2, 'baz' => 3);
$config        = new GeneratedHydrator\Configuration('Example');
$hydratorClass = $config->createFactory()->getHydratorClass();
$hydrators     = array(
    new $hydratorClass(),
    new Laminas\Hydrator\ClassMethods(),
    new Laminas\Hydrator\Reflection(),
    new Laminas\Hydrator\ArraySerializable(),
);

foreach ($hydrators as $hydrator) {
    $start = microtime(true);

    for ($i = 0; $i < $iterations; $i += 1) {
        $hydrator->hydrate($data, $object);
        $hydrator->extract($object);
    }

    var_dump(microtime(true) - $start);
}

This will produce something like following:

0.028156042098999s
2.606673002243s
0.56710886955261s
0.60278487205505s

As you can see, the generated hydrator is 20 times faster than Laminas\Hydrator\Reflection and Laminas\Hydrator\ArraySerializable, and more than 90 times faster than Laminas\Hydrator\ClassMethods.

Tuning for Production

By default, GeneratedHydrator will generate hydrators on every new request. While this is relatively fast, it will cause I/O operations, and you can achieve even better performance by pre-generating your hydrators and telling your application to autoload them instead of generating new ones at each run.

Avoiding regeneration involves:

  1. pre-generating your hydrators
  2. ensuring that your autoloader is aware of them

The instructions that follow assume you are using Composer.

Pre-generating your hydrators

There is no built-in way to bulk-generate all required hydrators, so you will need to do so on your own.

Here is a simple snippet you can use to accomplish this:

require '/path/to/vendor/autoload.php'; // composer autoloader

// classes for which we want to pre-generate the hydrators
$classes = [
    \My\Namespace\ClassOne::class,
    \My\Namespace\ClassTwo::class,
    \My\Namespace\ClassThree::class,
];

foreach ($classes as $class) {
    $config = new \GeneratedHydrator\Configuration($class);

    $config->setGeneratedClassesTargetDir('/path/to/target-dir');
    $config->createFactory()->getHydratorClass();
}

Just add all the classes for which you need hydrators to the $classes array, and have your deployment process run this script. When complete, all of the hydrators you need will be available in /path/to/target-dir.

Making the autoloader aware of your hydrators

Using your pre-generated hydrators is as simple as adding the generation target directory to your composer.json:

{
    "autoload": {
        "classmap": [
            "/path/to/target-dir"
        ]
    }
}

After generating your hydrators, have your deployment script run composer dump-autoload to regenerate your autoloader. From now on, GeneratedHydrator will skip code generation and I/O if a generated class already exists.

Fallback autoloader

Alternatively, GeneratedHydrator comes with a built-in autoloader that you can register on your own. This simplifies deployment, but is a bit slower:

$config = new \GeneratedHydrator\Configuration(\My\Namespace\ClassOne::class);

spl_autoload_register($config->getGeneratedClassAutoloader());

// now simply use your hydrator, and if possible, code generation will be skipped:
$hydratorName = $config->createFactory()->getHydratorClass();
$hydrator     = new $hydratorName();

Contributing

Please read the CONTRIBUTING.md contents if you wish to help out!

More Repositories

1

ProxyManager

🎩✨🌈 OOP Proxy wrappers/utilities - generates and manages proxies of your objects
PHP
4,913
star
2

PackageVersions

📦 Composer addon to efficiently get installed packages' version numbers
PHP
3,245
star
3

DoctrineBatchUtils

âž¿ A set of utilities to operate with Doctrine ORM's batch processing techniques
PHP
324
star
4

PSR7Csrf

â›” PSR-7 storage-less CSRF token generation/validation
PHP
182
star
5

Doctrine2StepHydration

Example repository to demonstrate 2-step fetch-join hydration with Doctrine2
PHP
98
star
6

event-sourcing-workshop

WIP: workshop materials for https://2022.websummercamp.com/
PHP
97
star
7

CodeGenerationUtils

A set of code generator utilities built on top of PHP-Parsers that ease its use when combined with Reflection
PHP
93
star
8

LazyMap

🌈 A lazy-initializing high performance service map
PHP
87
star
9

Finalizer

A simple utility library that checks for PHP classes that should or shouldn't be marked as final
PHP
79
star
10

Instantiator

🌟 Instantiate PHP objects without constructors calls
PHP
70
star
11

LazyProperty

🌈 An utility to lazy-initialize object properties
PHP
69
star
12

ChangeSet

📼 A simple changeset list that supports operations like insert/update/delete, event triggering, commits and rollbacks
PHP
69
star
13

doctrine-orm-zf2-tutorial

📚 Doctrine 2 ORM and Zend Framework 2 integration tutorial
59
star
14

OcraCachedViewResolver

🚄 Cached view template resolvers for `laminas/laminas-view` - to avoid additional stat calls while rendering views
PHP
57
star
15

proxy-pattern-in-php

📚 A short presentation/introduction to the Proxy OOP patterns applied to PHP
HTML
52
star
16

OcraServiceManager

ServiceManager additional features implemented via modules
PHP
47
star
17

extremely-defensive-php

CSS
47
star
18

ocramius.github.com

📚 Coding thoughts and ideas by Ocramius
JavaScript
40
star
19

home-automation

Shell
35
star
20

example-symfony-cli-usage

Example repository to demonstrate "correct" (opinionated) symfony console application usage with a DIC
32
star
21

doctrine-best-practices

Slides for my "doctrine best practices" talk
CSS
28
star
22

Doctrine2ORMSlidesTutorial

A slideshow that acts as a Tutorial for Doctrine 2 ORM newcomers
HTML
28
star
23

ocramius.util.Optional

📦 A PHP port of java.util.Optional as in the OpenJDK
PHP
27
star
24

OcraHopHop

🚆 Worker-based HTTP request dispatching module for ZF2
PHP
26
star
25

.github

Common documentation about my work on projects that I make public on Github
26
star
26

OcraDiCompiler

Zend\Di compiler utility module to make ZF2 applications blazing fast
PHP
25
star
27

basic-doctrine-tutorial-2017

PHP
23
star
28

doctrine-tutorial-bootstrapper

PHP
21
star
29

zf2-best-practices

An opinionated approach to ZendFramework 2 development practices
CSS
20
star
30

OcraElasticSearch

ElasticSearch Zend Framework 2 Module based on top of a Doctrine ObjectManager
PHP
20
star
31

Exam

Simple exam service prototype with event-driven PHP
PHP
18
star
32

real-time-applications-and-event-sourcing-in-php

[WIP] - PHPCon.pl 2015 workshop material
CSS
18
star
33

VersionEyeModule

VersionEye API integration module for ZF2
PHP
16
star
34

MinifyLessCSS

Combines, minifies, and caches JavaScript, LESS and CSS files through Minify and LessPHP
16
star
35

dpc-2016-cqrs-es-tutorial

PHP
15
star
36

zf2-dpc-tutorial-slides

📚 Slides for the "ZF2: From noob to pro" tutorial for @dpcon
CSS
15
star
37

a-complex-orm-faster-than-sql

✨ 💥 🔥 ⚡
HTML
14
star
38

from-helpers-to-middleware

HTML
14
star
39

harvest-to-jira-tempo-time-sync

Synchronizes logged time from Harvest to Tempo (Jira)
PHP
14
star
40

OcraLoremModule

Module that provides Lorem Generator utilities for ZendFramework 2 Applications
PHP
14
star
41

crossdomain-iframe-resizing

Cross-Domain dynamic resizing of iFrames
JavaScript
14
star
42

RoutingExamples

📚 Dynamic ZendFramework routing examples (repository-backed routing)
PHP
13
star
43

php-benelux-2017-cqrs-es-tutorial

PHP
13
star
44

ShittyCQRSPresentation

A shitty presentation for a shitty talk
HTML
12
star
45

ocramius-cli

The Ocramius - do I have to say anything else?
PHP
11
star
46

ZfMicroFramework

Zend Framework 2 based Micro Framework PoC
PHP
9
star
47

ZfKickstarter

Kickstart your ZendFramework project by using this repo as a base for your projects
9
star
48

PhpCodeInliner

PHP
8
star
49

OcraComposer

Zend Framework 2 Module that provides Composer based autoloading for Zend Skeleton Application based installations
PHP
7
star
50

Comcom-Exam

A simple structure for an event-driven exam application design
PHP
6
star
51

voodoo-php

Slides for my "voodoo php" talk
CSS
6
star
52

ZfPhpcrOdm

PHPCR-ODM Zend Framework 2 Module
PHP
6
star
53

doctrine-orm-and-zendframework-2

📚
HTML
6
star
54

building-a-microframework-with-zf

How to use ZF3 components to effectively achieve code-reuse across different PSR-7 compliant frameworks
CSS
6
star
55

doctrine2-zf2-introduction

📚
5
star
56

virtualized-development-environment

A virtualized development environment based on Vagrant and Chef
Ruby
5
star
57

ZfPhpcrOdmSample

PHPCR-ODM Zend Framework 2 Sample "Consumer" Module
PHP
5
star
58

OpenCartDoctrineSchema

An OpenCart 2.1-rc schema converted to Doctrine ORM entities, and with foreign keys included (not maintained)
PHP
5
star
59

example-post-persist-entity-listener

An example repository demonstrating how to publish/subscribe to entity changes in a transactional-safe way
PHP
4
star
60

BetterReflection

[WIP] Polyfill for the PHP Reflection API that we miss
4
star
61

array_change_keys-benchmark

Benchmarks the array_change_keys RFC (see https://wiki.php.net/rfc/array_change_keys)
PHP
4
star
62

crate-pdo

Crate PDO Adapter (incubator)
PHP
4
star
63

brnophp-2014-slides

📚
HTML
3
star
64

example-angular1-webpack-karma

example-angular1-webpack-karma
JavaScript
3
star
65

marco-pivetta.com

Sources of my static website at https://marco-pivetta.com/
HTML
3
star
66

stack-csp

Stack middleware for generating Content Security Policy (CSP 1.0) HTTP headers for the request
PHP
3
star
67

ocrami.us

HTML
3
star
68

JsMarioSandbox

A sandbox where to play around with a small super mario alike game
JavaScript
3
star
69

FizzBuzzTestingExample

Just an example used to demonstrate some basic testing approaches around FizzBuzz (in classroom)
PHP
3
star
70

StOgame

Standard Ogame Project - Making Ogame a better place
JavaScript
2
star
71

automatic-releases

PHP
2
star
72

example-zf3-error-handling

Example ZF3 application with PRs demonstrating how to improve error handling
HTML
2
star
73

just-trying-automated-releases

2
star
74

SecurityAdvisoriesBuilder-hs

Haskell
2
star
75

OcraComposerInstaller

Installation helper package that handles installation of ZendFramework Modules via Composer
PHP
2
star
76

proxies-in-php

📚 A presentation about OOP Proxies, what they can do and how we can use them
2
star
77

Component_ZendCode

Code component from Zend Framework 2
PHP
2
star
78

zf2-tag-sync

🔄 Repository used to manage releases of subtree-splits of zf2
PHP
2
star
79

just-testing-some-github-hooks

1
star