在 JMS 序列化程序中排除空属性
Exclude null properties in JMS Serializer
我使用的 XML API 有一个选项可以只检索部分响应。
如果使用此功能,这会导致生成的对象具有很多 NULL
属性。
有没有办法真正跳过 NULL
属性?我尝试使用
实施排除策略
shouldSkipProperty(PropertyMetadata $property, Context $context)`
但我意识到无法访问当前的 属性 值。
示例如下class
class Hotel {
/**
* @Type("string")
*/
public $id;
/**
* @Type("integer")
*/
public $bookable;
/**
* @Type("string")
*/
public $name;
/**
* @Type("integer")
*/
public $type;
/**
* @Type("double")
*/
public $stars;
/**
* @Type("MssPhp\Schema\Response\Address")
*/
public $address;
/**
* @Type("integer")
*/
public $themes;
/**
* @Type("integer")
*/
public $features;
/**
* @Type("MssPhp\Schema\Response\Location")
*/
public $location;
/**
* @Type("MssPhp\Schema\Response\Pos")
*/
public $pos;
/**
* @Type("integer")
*/
public $price_engine;
/**
* @Type("string")
*/
public $language;
/**
* @Type("integer")
*/
public $price_from;
}
在这个特定的 api 调用中反序列化到具有大量 null
属性的以下对象。
"hotel": [
{
"id": "11230",
"bookable": 1,
"name": "Hotel Test",
"type": 1,
"stars": 3,
"address": null,
"themes": null,
"features": null,
"location": null,
"pos": null,
"price_engine": 0,
"language": "de",
"price_from": 56
}
]
但我希望它是
"hotel": [
{
"id": "11230",
"bookable": 1,
"name": "Hotel Test",
"type": 1,
"stars": 3,
"price_engine": 0,
"language": "de",
"price_from": 56
}
]
您可以配置 JMS 序列化程序以跳过 null
属性,如下所示:
$serializer = JMS\SerializerBuilder::create();
$serializedString = $serializer->serialize(
$data,
'xml',
JMS\SerializationContext::create()->setSerializeNull(true)
);
摘自 this issue.
更新:
不幸的是,如果您在反序列化时不想要空属性,除了自己删除它们之外别无他法。
但是,我不确定您实际想要删除这些属性的用例是什么,但看起来 Hotel
class 不包含太多逻辑。在这种情况下,我想知道结果是否应该是 class ?
我认为将数据表示为关联数组而不是对象会更自然。当然,JMS Serializer 无法将您的数据反序列化为数组,因此您将需要一个数据传输对象。
将 dumpArray
和 loadArray
方法添加到现有 Hotel
class 就足够了。这些将用于将数据转换为您想要的结果,反之亦然。有你的DTO。
/**
* Sets the object's properties based on the passed array
*/
public function loadArray(array $data)
{
}
/**
* Returns an associative array based on the objects properties
*/
public function dumpArray()
{
// filter out the properties that are empty here
}
我认为这是最干净的方法,它可能反映出您正在尝试做更多的事情。
希望对您有所帮助。
我使用的 XML API 有一个选项可以只检索部分响应。
如果使用此功能,这会导致生成的对象具有很多 NULL
属性。
有没有办法真正跳过 NULL
属性?我尝试使用
shouldSkipProperty(PropertyMetadata $property, Context $context)`
但我意识到无法访问当前的 属性 值。
示例如下class
class Hotel {
/**
* @Type("string")
*/
public $id;
/**
* @Type("integer")
*/
public $bookable;
/**
* @Type("string")
*/
public $name;
/**
* @Type("integer")
*/
public $type;
/**
* @Type("double")
*/
public $stars;
/**
* @Type("MssPhp\Schema\Response\Address")
*/
public $address;
/**
* @Type("integer")
*/
public $themes;
/**
* @Type("integer")
*/
public $features;
/**
* @Type("MssPhp\Schema\Response\Location")
*/
public $location;
/**
* @Type("MssPhp\Schema\Response\Pos")
*/
public $pos;
/**
* @Type("integer")
*/
public $price_engine;
/**
* @Type("string")
*/
public $language;
/**
* @Type("integer")
*/
public $price_from;
}
在这个特定的 api 调用中反序列化到具有大量 null
属性的以下对象。
"hotel": [
{
"id": "11230",
"bookable": 1,
"name": "Hotel Test",
"type": 1,
"stars": 3,
"address": null,
"themes": null,
"features": null,
"location": null,
"pos": null,
"price_engine": 0,
"language": "de",
"price_from": 56
}
]
但我希望它是
"hotel": [
{
"id": "11230",
"bookable": 1,
"name": "Hotel Test",
"type": 1,
"stars": 3,
"price_engine": 0,
"language": "de",
"price_from": 56
}
]
您可以配置 JMS 序列化程序以跳过 null
属性,如下所示:
$serializer = JMS\SerializerBuilder::create();
$serializedString = $serializer->serialize(
$data,
'xml',
JMS\SerializationContext::create()->setSerializeNull(true)
);
摘自 this issue.
更新:
不幸的是,如果您在反序列化时不想要空属性,除了自己删除它们之外别无他法。
但是,我不确定您实际想要删除这些属性的用例是什么,但看起来 Hotel
class 不包含太多逻辑。在这种情况下,我想知道结果是否应该是 class ?
我认为将数据表示为关联数组而不是对象会更自然。当然,JMS Serializer 无法将您的数据反序列化为数组,因此您将需要一个数据传输对象。
将 dumpArray
和 loadArray
方法添加到现有 Hotel
class 就足够了。这些将用于将数据转换为您想要的结果,反之亦然。有你的DTO。
/**
* Sets the object's properties based on the passed array
*/
public function loadArray(array $data)
{
}
/**
* Returns an associative array based on the objects properties
*/
public function dumpArray()
{
// filter out the properties that are empty here
}
我认为这是最干净的方法,它可能反映出您正在尝试做更多的事情。
希望对您有所帮助。