dc / json
JSON Serializer
Requires
- php: >=5.6.0
- phpdocumentor/reflection-docblock: 2.*
Requires (Dev)
- dc/cache: dev-master
- dc/ioc: dev-master
- phpunit/phpunit: 4.0.*
This package is not auto-updated.
Last update: 2024-11-09 19:09:50 UTC
README
Allow serializing directly to classes using only phpDoc and type hints.
Installation
$ composer install dc/json
Or add it to composer.json
:
"require": { "dc/json": "0.*" }
$ composer install
This package suggests dc/ioc
and dc/cache
, but it really is a very strong recommendation. It will be painful or slow to use without it.
Getting started
Get hold of a new \DC\JSON\Serializer
and start serializing:
class Cat { /** @var string */ public $name; } $json = '[{ "name": "Sniffles" }, { "name": "Snuggles" }]'; $serializer = new \DC\JSON\Serializer(); $cats = $serializer->deserialize($catsJson, '\Cat[]');
If you are using a dc/ioc
container, you'll need to do this:
\DC\JSON\IoC\SerializerSetup::setup($container);
Serialization handlers
You can register a serialization handler to change how a specific class is serialized. This is different from using the
JsonSerializable
interface in PHP, as a serialization handler allows you to change how built-in classes are serialized
and deserialized.
The interface itself is easy to implement. The library comes with one default handler, which serializes \DateTime
objects to and from ISO-8601 format. Look at that handler for a good example.
If you want to register serialization your own handlers, it is easiest to do using IoC:
$container->register('\MyHandler')->to('\DC\JSON\Handler')->withContainerLifetime();
How classes are constructed
Classes are constructed in this manner:
- Look for the property names in the constructor. Use the constructor to fill in those values.
- Look for public setters of the form
setX
for the remaining values (this is controlled by convention, which you can override). Use them. - Look for public properties for the remaining values.
So, given this class:
class Cat { private $name; private $age; public $paws = 4; function __construct($name) { $this->name = $name; } function setAge($age) { $this->age = $age; } }
...and this JSON:
{ "name": "Snuggles", "age": 6, "paws": 4 }
...These two are equivalent:
$cat = $serializer->deserialize($json, '\Cat'); // or $cat = new \Cat("Snuggles"); $cat->setAge(6); $cat->paws = 4;
Performance
It is no secret that json_decode
and json_encode
is a lot faster than this package. In fact, we use those internally
for the actual serialization. The magic of this package gets applied before serialization and after deserialization.
Using a combination of type hints and documentation, we are smart about constructing your objects the way they were intended to be constructed. But, parsing your documentation is resource intensive, therefore it is good practice to heed a few rules:
- Try to keep the serializer instance around for multiple serializations. All of the reflection happens only the first time a class is encountered.
- Install
dc/cache
anddc/cache-memcache
, and provide it to the serializer. If you do, all the information obtained from the reflection is cached for a while.
When using a primed cache, deserializing is about 4-5 times as slow a json_decode
.