ad-astra / serializer
php serializer
Requires
- php: >=8.1
This package is auto-updated.
Last update: 2025-07-14 23:18:11 UTC
README
Fast, simple and reliable php serializer, allows convert object to string of the specified format (only json and urlencoded
supported now) and vice versa: creating object from string (json format) - deserialization process
Supporting
- normalization groups
- circular reference
- normalization depth
- composite keys
- array types (via attributes)
- enums (include typed)
- straight access to properties or via getter/setter
Usage
- Basic
- Skipping null values
- Using groups
- Naming
- Typed arrays
- Serialization and Deserialization strategy
Basic
Let's imagine that we have a class
class Order { public string $id; public float $price; public array $products; }
Create an instance
$order = new Order(); $order->id = 1; $order->price = 100.5;
Now, init the serializer
$serializer = new Serializer([new ObjectNormalizer()], ['json' => new JsonEncoder()]);
The last step, serialize to string:
$str = $serializer->serialize($order, 'json');
$str
will be equal json (of course not formatted):
{ "id": "123-abc", "price": 100.5, "products": null }
It's possible to convert string to object, just specify the object type:
$order = $serializer->deserialize($str, Order::class, 'json'); // output // object(Order)#11 (2) { ["id"]=> string(7) "123-abc" ["price"]=> float(100.5) ["products"]=> uninitialized(array) }
Skipping null values
Helpful option, if you want to omit null values, pass constant SKIP_NULL_VALUES to context like this
$str = $serializer->serialize($order, 'json', context: [ObjectNormalizer::SKIP_NULL_VALUES]);
output
{ "id": "123-abc", "price": 100.5 }
Using groups
You can specify what properties should be serialize/deserialize via groups
Let's add some groups to our Order
class
#[Groups(['group_1', 'group_2'])] public string $id; #[Groups(['group_2', 'group_3'])] public float $price;
Now, if you pass a group to serialise
method, it will be process properties that match given groups
$str = $serializer->serialize($order, 'json', ['group_1']);
will output
{ "id": "123-abc" }
because only id
have attribute #Groups
with group group_1
,
but if we pass group_2
, we already have id
and price
$str = $serializer->serialize($order, 'json', ['group_2']);
will output
{ "id": "123-abc", "price": 100.5 }
You can pass multiple groups, any property, that have one of passed group name, will be serialized
$str = $serializer->serialize($order, 'json', ['group_1', 'group_3']);
will output
{ "id": "123-abc", "price": 100.5 }
There is one special group *
, property will be serialized, if it has at least one any group
$str = $serializer->serialize($order, 'json', ['*']);
will output
{ "id": "123-abc", "price": 100.5 }
This also good works with denormalization process.
Naming
Sometimes it's necessary to rename a property, you can achieve this by using Name
attribute
#[Name('orderId')] public string $id;
will output
{ "orderId": "123-abc" }
Or you want to nest a property? Not a good idea to make several object for this.
Just pass SIMPLIFY_COMPOSITE_KEYS
via context, this option will split with dot symbol .
the specified
property name into nested object!
// Dont forget to pass SIMPLIFY_COMPOSITE_KEYS!!! $str = $serializer->serialize($order, 'json', ['group_1'], [ObjectNormalizer::SIMPLIFY_COMPOSITE_KEYS]);
will output
{ "order": { "info": { "identifier": { "primary": "123-abc" } } } }
This also good works with denormalization process.
Typed arrays
Our order have some products
class Product { public string $name; public float $price; } ... $phone = new Product(); $phone->name = 'Samsung phone'; $phone->price = 100; $apple = new Product(); $apple->name = 'apple'; $apple->price = 7; $order->products = [$phone, $apple];
Lets try to serialize
$str = $serializer->serialize($order, 'json');
output
{ "id": "123-abc", "price": 100.5, "products": [ { "name": "Samsung phone", "price": 100 }, { "name": "apple", "price": 7 } ] }
Great! It works even with nested objects (all attributes and groups also works with nested object).
But what with deserialization? If there is an array with simply type like integer or string, there is no problem,
but we have array of object! Just specify the type you need via ArrayType
attribute
class Order { ... #[ArrayType(Product::class)] public array $products; } ... $order = $serializer->deserialize($str, Order::class, 'json'); //output //object(Order)#13 (3) { ["id"]=> string(7) "123-abc" ["price"]=> float(100.5) ["products"]=> array(2) { [0]=> object(Product)#17 (2) { ["name"]=> string(13) "Samsung phone" ["price"]=> float(100) } [1]=> object(Product)#21 (2) { ["name"]=> string(5) "apple" ["price"]=> float(7) } } }
That's it! You have Order
object with $products
array contained Product
objects!
Note, if you omit ArrayType
, you will get simply assoc php array, cause there's no info about array type.
Serialization and Deserialization strategy
You can even specify different behaviour for serialization/deserialization via NormalizationContext
and DenormalizationContext
by passing attributes into them.
example
class Order { ... #[NormalizationContext( new Groups(['group_1']), new Name('order.full_price') )] #[DenormalizationContext( new Groups(['group_2']), new Name('order_price') )] public float $price; ... } ... $str = $serializer->serialize($order, 'json', ['group_1']);
output:
{ "id": "123-abc", "full_price": 100.5 }
Lets try to deserialize
$order = $serializer->deserialize('{"id":"123-abc","order_price":100.5}', Order::class, 'json', ['group_2']); //output //object(Order)#11 (2) { ["id"]=> string(7) "123-abc" ["price"]=> float(100.5) ["products"]=> uninitialized(array) }