Giter Site home page Giter Site logo

sprayserializer's Introduction

SpraySerializer

Fast and easy serialization and deserialization of php objects.

Build Status

Internals

Serialization is performed by attaching to a specific class scope using the Closure::bind method. To keep things fast, reflection is only used while generating the serialization code.

How to use

Let's start with a class to serialize. Note that the annotations hint the serializer, and that they're required for deserializing objects.

/**
 * Person
 */
class Person
{
    /**
     * @var string
     */
    private $name;

    /**
     * @var Address
     */
    private $address;

    public function __construct($name, Address $address)
    {
        $this->name = (string) $name;
        $this->address = $address;
    }
}

/**
 * Address
 */
class Address
{
    /**
     * @var string
     */
    private $street;

    public function __construct($street)
    {
        $this->street = (string) $street;
    }
}

Then we'll initialize the serializer.

$serializer = new Serializer();
$serializer->attach(
    new ObjectListener(
        new SerializerLocator(
            new SerializerRegistry(),
            new ObjectSerializerGenerator(
                new AnnotationBackedPropertyInfo()
            ),
            new ArrayCache('Serializer')
        )
    )
);

Now we can serialize almost any object to an array and back to an object.

$data = $serializer->serialize(new Person('Name', new Address('Street')));
var_dump($data);
// array(2) {
//   'name' =>
//   string(4) "Name"
//   'address' =>
//   array(1) {
//     'street' =>
//     string(6) "Street"
//   }
// }


$object = $serializer->deserialize('Person', $data);
var_dump($object);
// class Person#8 (2) {
//   private $name =>
//   string(4) "Name"
//   private $address =>
//   class Address#18 (1) {
//     private $street =>
//     string(6) "Street"
//   }
// }

As the example above shows, the serializer uses default docblock annotations to determine the serialization strategy. The following annotations are supported:

class SerializeMe
{
    /**
     * @var string
     */
    private $string;

    /**
     * @var int
     */
    private $int;

    /**
     * @var integer
     */
    private $integer;

    /**
     * @var bool
     */
    private $bool;

    /**
     * @var boolean
     */
    private $boolean;

    /**
     * @var float
     */
    private $float;

    /**
     * @var double
     */
    private $double;

    /**
     * @var array
     */
    private $array;

    /**
     * @var Object
     */
    private $object;

    /**
     * @var string[]
     */
    private $stringArray;

    /**
     * @var Object[]
     */
    private $objectArray;

    /**
     * @var array<string>
     */
    private $stringArrayJavaStyle;

    /**
     * @var array<Object>
     */
    private $objectArrayJavaStyle;
}

There're some limitations to the implemented serialization method. For instance, deserializing a DateTime(Immutable) object is not possible. For this reason, specialized serializers are added. You'll need to add these to the SerializerRegistry in your application bootstrap like so:

$registry = new SerializerRegistry();
$registry->add(new DateTimeSerializer());
$registry->add(new DateTimeImmutableSerializer());
$registry->add(new StdClassSerializer());

$serializer = new Serializer();
$serializer->attach(
    new ObjectListener(
        new SerializerLocator(
            $registry,
            new ObjectSerializerGenerator(
                new AnnotationBackedPropertyInfo()
            ),
            new ArrayCache('Serializer')
        )
    )
);

In order to support object inheritance (de)serialization, just the annotations is not enough. The ObjectTypeListener is required to enable this functionality:

$serializer = new Serializer();
$serializer->attach(
    new ObjectTypeListener()
);
$serializer->attach(
    new ObjectListener(
        new SerializerLocator(
            new SerializerRegistry(),
            new ObjectSerializerGenerator(
                new AnnotationBackedPropertyInfo()
            ),
            new ArrayCache('Serializer')
        )
    )
);

Note: Enabling this feature results in your data populated with '__type' => 'ClassName'.

When your application requires encryption you'll have to attach the EncryptionListener:

$blockCipher = BlockCipher::factory('mcrypt', ['algo' => 'aes']);
$blockCipher->setKey('5eDCZRmyX8s7nbgV9f6pVrmRISdc5t8L');

$serializer = new Serializer();
$serializer->attach(
    new EncryptionListener(
        new EncryptorLocator(
            new EncryptorGenerator(new AnnotationBackedPropertyInfo()),
            new ArrayCache('Encryptor')
        ),
        $blockCipher
    )
);
$serializer->attach(
    new ObjectListener(
        new SerializerLocator(
            new SerializerRegistry(),
            new ObjectSerializerGenerator(
                new AnnotationBackedPropertyInfo()
            ),
            new ArrayCache('Serializer')
        )
    )
);

The library provides two methods of caching: array and file. The array cache is primarily useful for testing/development purposes. For production however, you're better off using the FileCache.

The file cache actually writes the generated serialization code to plain php files for later use (and therefore automatically cached in op-code cache).

Below is how you'd bootstrap the file cache for the serializer:

use Symfony\Component\Filesystem\Filesystem;

$serializer = new Serializer();
$serializer->attach(
    new ObjectListener(
        new SerializerLocator(
            new SerializerRegistry(),
            new ObjectSerializerGenerator(
                new AnnotationBackedPropertyInfo()
            ),
            new FileCache(new Filesystem(), '/path/to/cache/directory', 'Serializer')
        )
    )
);

sprayserializer's People

Contributors

jurjean avatar marek-binkowski-sim avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.