JMS 序列化程序。创建 2 种具有"one-to-many"关系的模型序列化方式



我正在为PHP项目使用JMS序列化程序,偶然发现了一个问题。

查看代码

<?php
use JMSSerializerAnnotation as Serializer;
/**
* @SerializerExclusionPolicy("all")
*/
class Order
{
/**
* @var int
* @SerializerType("integer")
* @SerializerExpose
*/
private $id;
/**
* @var Product[]
* @SerializerType("array<Product>")
* @SerializerExpose
*/
private $products;
/**
* @var float
* @SerializerType("float")
* @SerializerExpose
*/
private $total;
private $someInternalProperty;
function __construct($products)
{
$this->id = rand(0, 100);
$this->products = $products;
$this->total = rand(100, 1000);
$this->someInternalProperty = 'Flag';
}
}
/**
* @SerializerExclusionPolicy("all")
*/
class Product
{
/**
* @var int
* @SerializerType("integer")
* @SerializerExpose
*/
private $id;
/**
* @var string
* @SerializerType("string")
* @SerializerExpose
*/
private $name;
private $price;
private $description;
function __construct($id, $name, $price, $description)
{
$this->id = $id;
$this->name = $name;
$this->price = $price;
$this->description = $description;
}
}
$order = new Order([
new Product(
1,
'Banana',
10,
'Yellow'
),
new Product(
2,
'Tomato',
12,
'Red'
)
]);
$serializer = JMSSerializerSerializerBuilder::create()
->setPropertyNamingStrategy(new JMSSerializerNamingSerializedNameAnnotationStrategy(new JMSSerializerNamingIdenticalPropertyNamingStrategy()))
->build();
print_r(
$serializer->serialize(
$order,
'json',
JMSSerializerSerializationContext::create()
->setSerializeNull(true)
)
);

在这里,我展示了我的代码的简化示例。我用它来存储订单更改的历史记录。在更新之前和之后,我将这个序列化的模型保存到数据库中。好的。

现在,我想用所有属性序列化Product的模型,以便在客户端工作。所以我的第一个想法是使用分组。我需要为$id和$name属性设置"Group({'history','edit'})",并为所有其他"Group({'edit'})"。好的,它适用于产品序列化,但它破坏了第一个解决方案。现在,我的"订单历史记录"存储了不必要的信息,如$price和$description。

如果没有隐式指定序列化组(如Orders的历史示例),是否有一些正确的方法来指定将要使用的产品模型的默认组?或者以其他方式使这两种类型的序列化可用,而无需将组移动到Order的模型中(因为在这种情况下,实际上有不止一个模型需要重构)。

对不起。我发现,如果我使用一个组"默认",所有的工作都是正确的。

<?php
require_once __DIR__ . '/../../../app/Autoload.php';
use JMSSerializerAnnotation as Serializer;
/**
* @SerializerExclusionPolicy("all")
*/
class Order
{
/**
* @var int
* @SerializerType("integer")
* @SerializerExpose
*/
private $id;
/**
* @var Product[]
* @SerializerType("array<Product>")
* @SerializerExpose
*/
private $products;
/**
* @var float
* @SerializerType("float")
* @SerializerExpose
*/
private $total;
private $someInternalProperty;
function __construct($products)
{
$this->id = rand(0, 100);
$this->products = $products;
$this->total = rand(100, 1000);
$this->someInternalProperty = 'Flag';
}
}
/**
* @SerializerExclusionPolicy("all")
*/
class Product
{
/**
* @var int
* @SerializerExpose
* @SerializerType("integer")
* @SerializerGroups({"Default", "edit"})
*/
private $id;
/**
* @var string
* @SerializerExpose
* @SerializerType("string")
* @SerializerGroups({"Default", "edit"})
*/
private $name;
/**
* @SerializerExpose
* @SerializerGroups({"edit"})
*/
private $price;
/**
* @SerializerExpose
* @SerializerGroups({"edit"})
*/
private $description;
private $hiddenProperty;
function __construct($id, $name, $price, $description)
{
$this->id = $id;
$this->name = $name;
$this->price = $price;
$this->description = $description;
$this->hiddenProperty = 42;
}
}
$product1 = new Product(
1,
'Banana',
10,
'Yellow'
);
$order = new Order([
$product1,
new Product(
2,
'Tomato',
12,
'Red'
)
]);
$serializer = JMSSerializerSerializerBuilder::create()
->setPropertyNamingStrategy(new JMSSerializerNamingSerializedNameAnnotationStrategy(new JMSSerializerNamingIdenticalPropertyNamingStrategy()))
->build();
print_r([
$serializer->serialize(
$order,
'json',
JMSSerializerSerializationContext::create()
->setSerializeNull(true)
->setGroups(['Default'])
),
$serializer->serialize(
$product1,
'json',
JMSSerializerSerializationContext::create()
->setSerializeNull(true)
->setGroups(['edit'])
),
]);

结果是:

Array
(
[0] => {"id":86,"products":[{"id":1,"name":"Banana"},{"id":2,"name":"Tomato"}],"total":644} // Here I have short model for history
[1] => {"id":1,"name":"Banana","price":10,"description":"Yellow"} // And here I have expanded model for other purpose.
)

我喜欢JMS序列化程序:)

最新更新