ad-astra/serializer
php序列化器
Requires
- php: >=8.1
This package is auto-updated.
Last update: 2024-09-14 21:25:55 UTC
README
快速、简单、可靠的php序列化器,允许将对象转换为指定格式的字符串(目前仅支持json和urlencoded)
以及相反:从字符串(json格式)创建对象 - 反序列化过程
支持
- 规范化组
- 循环引用
- 规范化深度
- 复合键
- 数组类型(通过属性)
- 枚举(包括类型化)
- 直接访问属性或通过getter/setter
使用方法
基本
假设我们有一个类
class Order { public string $id; public float $price; public array $products; }
创建一个实例
$order = new Order(); $order->id = 1; $order->price = 100.5;
现在,初始化序列化器
$serializer = new Serializer([new ObjectNormalizer()], ['json' => new JsonEncoder()]);
最后一步,序列化为字符串
$str = $serializer->serialize($order, 'json');
$str
将等于json(当然不是格式化的)
{ "id": "123-abc", "price": 100.5, "products": null }
可以将字符串转换为对象,只需指定对象类型
$order = $serializer->deserialize($str, Order::class, 'json'); // output // object(Order)#11 (2) { ["id"]=> string(7) "123-abc" ["price"]=> float(100.5) ["products"]=> uninitialized(array) }
跳过null值
有用的选项,如果您想省略null值,可以将常量SKIP_NULL_VALUES传递到上下文中,如下所示
$str = $serializer->serialize($order, 'json', context: [ObjectNormalizer::SKIP_NULL_VALUES]);
输出
{ "id": "123-abc", "price": 100.5 }
使用组
您可以通过组指定应该序列化/反序列化的属性
让我们给我们的Order
类添加一些组
#[Groups(['group_1', 'group_2'])] public string $id; #[Groups(['group_2', 'group_3'])] public float $price;
现在,如果您将一个组传递给serialise
方法,它将处理匹配给定组的属性
$str = $serializer->serialize($order, 'json', ['group_1']);
将输出
{ "id": "123-abc" }
因为只有id
有属性#Groups
与组group_1
匹配,
但如果我们传递group_2
,我们已经有了id
和price
$str = $serializer->serialize($order, 'json', ['group_2']);
将输出
{ "id": "123-abc", "price": 100.5 }
您可以通过传递多个组来指定,任何具有传入组名称之一的属性都将被序列化
$str = $serializer->serialize($order, 'json', ['group_1', 'group_3']);
将输出
{ "id": "123-abc", "price": 100.5 }
有一个特殊组*
,如果属性至少有一个任何组,则将被序列化
$str = $serializer->serialize($order, 'json', ['*']);
将输出
{ "id": "123-abc", "price": 100.5 }
这也适用于去规范化过程。
命名
有时需要重命名属性,您可以通过使用Name
属性来实现
#[Name('orderId')] public string $id;
将输出
{ "orderId": "123-abc" }
或者您想嵌套一个属性?为了这个目的创建几个对象不是好主意。
只需通过上下文传递SIMPLIFY_COMPOSITE_KEYS
,这个选项将使用点符号.
拆分指定的
属性名称到嵌套对象!
// Dont forget to pass SIMPLIFY_COMPOSITE_KEYS!!! $str = $serializer->serialize($order, 'json', ['group_1'], [ObjectNormalizer::SIMPLIFY_COMPOSITE_KEYS]);
将输出
{ "order": { "info": { "identifier": { "primary": "123-abc" } } } }
这也适用于去规范化过程。
类型化数组
我们的订单有一些产品
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];
让我们尝试序列化
$str = $serializer->serialize($order, 'json');
输出
{ "id": "123-abc", "price": 100.5, "products": [ { "name": "Samsung phone", "price": 100 }, { "name": "apple", "price": 7 } ] }
太棒了!它甚至可以处理嵌套对象(所有属性和组也适用于嵌套对象)。
但是反序列化怎么办?如果数组中是简单类型如整数或字符串,则没有问题,但我们有对象数组!只需通过ArrayType
属性指定所需的类型
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) } } }
就这样!您有了Order
对象,其中包含包含Product
对象的$products
数组!
注意,如果您省略了ArrayType
,您将得到简单的关联php数组,因为没有关于数组类型的信息。
序列化和反序列化策略
您甚至可以通过将属性传递到NormalizationContext
和DenormalizationContext
中来指定序列化/反序列化的不同行为。示例
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']);
输出
{ "id": "123-abc", "full_price": 100.5 }
让我们尝试反序列化
$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) }