如何使用 Symfony 中的 JMS 序列化程序将空数组序列化为 JSON 对象(花括号)
How to serialize empty array to JSON object (curly braces) with JMS Serializer in Symfony
有以下PHPclass
class SampleObject
{
private $map;
private $array;
public function getMap(): array
{
return $map;
}
public function setMap(array $map)
{
$this->map = $map;
}
public function getArray(): array
{
return $this->array;
}
public function setArray(array $array) {
$this->array = $array;
}
}
和两个实例:
$inst1 = new SampleObject();
$inst2 = new SampleObject();
$inst1->setMap(['key' => 'value']);
$inst1->setArray([1]);
$inst2->setMap([]);
$inst2->setArray([]);
当使用 JMS Serializer 将它们序列化为 json 时,第一个变为:
{"map": {"key": "value"}, "array": [1]}
第二个:
{"map": [], "array": []}
如何强制序列化程序将第二个对象序列化为 {"map": {}, "array": []}
?
正如@EmanuelOster 在评论中建议的那样,custom handler 可用于此目的。虽然该解决方案并不完美(现场注释会好得多),但它确实有效。这是一个示例处理程序
class SampleObjectSerializer implements SubscribingHandlerInterface {
public static function getSubscribingMethods() {
return [
[
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => SampleObject::class,
'method' => 'serialize',
],
];
}
public function serialize(JsonSerializationVisitor $visitor, SampleObject $object, array $type, Context $context) {
return [
'array' => $object->getArray(),
'map' => $this->emptyArrayAsObject($object->getMap()),
];
}
/**
* Forces to searialize empty array as json object (i.e. {} instead of []).
* @see
*/
private function emptyArrayAsObject(array $array) {
if (count($array) == 0) {
return new \stdClass();
}
return $array;
}
}
如果使用 Symfony,您需要 register it。
您可以通过在 serialize
方法上设置上下文信息(或使用注释等)来修改数组序列化行为
您将在 cookbook:
中找到这些关于序列化数组和散列的示例
<?php
// default (let the PHP's json_encode function decide)
$serializer->serialize([1, 2]); // [1, 2]
$serializer->serialize(['a', 'b']); // ['a', 'b']
$serializer->serialize(['c' => 'd']); // {"c" => "d"}
// same as default (let the PHP's json_encode function decide)
$serializer->serialize([1, 2], SerializationContext::create()->setInitialType('array')); // [1, 2]
$serializer->serialize([1 => 2], SerializationContext::create()->setInitialType('array')); // {"1": 2}
$serializer->serialize(['a', 'b'], SerializationContext::create()->setInitialType('array')); // ['a', 'b']
$serializer->serialize(['c' => 'd'], SerializationContext::create()->setInitialType('array')); // {"c" => "d"}
// typehint as strict array, keys will be always discarded
$serializer->serialize([], SerializationContext::create()->setInitialType('array<integer>')); // []
$serializer->serialize([1, 2], SerializationContext::create()->setInitialType('array<integer>')); // [1, 2]
$serializer->serialize(['a', 'b'], SerializationContext::create()->setInitialType('array<integer>')); // ['a', 'b']
$serializer->serialize(['c' => 'd'], SerializationContext::create()->setInitialType('array<string>')); // ["d"]
// typehint as hash, keys will be always considered
$serializer->serialize([], SerializationContext::create()->setInitialType('array<integer,integer>')); // {}
$serializer->serialize([1, 2], SerializationContext::create()->setInitialType('array<integer,integer>')); // {"0" : 1, "1" : 2}
$serializer->serialize(['a', 'b'], SerializationContext::create()->setInitialType('array<integer,integer>')); // {"0" : "a", "1" : "b"}
$serializer->serialize(['c' => 'd'], SerializationContext::create()->setInitialType('array<string,string>')); // {"d" : "d"}
有以下PHPclass
class SampleObject
{
private $map;
private $array;
public function getMap(): array
{
return $map;
}
public function setMap(array $map)
{
$this->map = $map;
}
public function getArray(): array
{
return $this->array;
}
public function setArray(array $array) {
$this->array = $array;
}
}
和两个实例:
$inst1 = new SampleObject();
$inst2 = new SampleObject();
$inst1->setMap(['key' => 'value']);
$inst1->setArray([1]);
$inst2->setMap([]);
$inst2->setArray([]);
当使用 JMS Serializer 将它们序列化为 json 时,第一个变为:
{"map": {"key": "value"}, "array": [1]}
第二个:
{"map": [], "array": []}
如何强制序列化程序将第二个对象序列化为 {"map": {}, "array": []}
?
正如@EmanuelOster 在评论中建议的那样,custom handler 可用于此目的。虽然该解决方案并不完美(现场注释会好得多),但它确实有效。这是一个示例处理程序
class SampleObjectSerializer implements SubscribingHandlerInterface {
public static function getSubscribingMethods() {
return [
[
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => SampleObject::class,
'method' => 'serialize',
],
];
}
public function serialize(JsonSerializationVisitor $visitor, SampleObject $object, array $type, Context $context) {
return [
'array' => $object->getArray(),
'map' => $this->emptyArrayAsObject($object->getMap()),
];
}
/**
* Forces to searialize empty array as json object (i.e. {} instead of []).
* @see
*/
private function emptyArrayAsObject(array $array) {
if (count($array) == 0) {
return new \stdClass();
}
return $array;
}
}
如果使用 Symfony,您需要 register it。
您可以通过在 serialize
方法上设置上下文信息(或使用注释等)来修改数组序列化行为
您将在 cookbook:
中找到这些关于序列化数组和散列的示例<?php
// default (let the PHP's json_encode function decide)
$serializer->serialize([1, 2]); // [1, 2]
$serializer->serialize(['a', 'b']); // ['a', 'b']
$serializer->serialize(['c' => 'd']); // {"c" => "d"}
// same as default (let the PHP's json_encode function decide)
$serializer->serialize([1, 2], SerializationContext::create()->setInitialType('array')); // [1, 2]
$serializer->serialize([1 => 2], SerializationContext::create()->setInitialType('array')); // {"1": 2}
$serializer->serialize(['a', 'b'], SerializationContext::create()->setInitialType('array')); // ['a', 'b']
$serializer->serialize(['c' => 'd'], SerializationContext::create()->setInitialType('array')); // {"c" => "d"}
// typehint as strict array, keys will be always discarded
$serializer->serialize([], SerializationContext::create()->setInitialType('array<integer>')); // []
$serializer->serialize([1, 2], SerializationContext::create()->setInitialType('array<integer>')); // [1, 2]
$serializer->serialize(['a', 'b'], SerializationContext::create()->setInitialType('array<integer>')); // ['a', 'b']
$serializer->serialize(['c' => 'd'], SerializationContext::create()->setInitialType('array<string>')); // ["d"]
// typehint as hash, keys will be always considered
$serializer->serialize([], SerializationContext::create()->setInitialType('array<integer,integer>')); // {}
$serializer->serialize([1, 2], SerializationContext::create()->setInitialType('array<integer,integer>')); // {"0" : 1, "1" : 2}
$serializer->serialize(['a', 'b'], SerializationContext::create()->setInitialType('array<integer,integer>')); // {"0" : "a", "1" : "b"}
$serializer->serialize(['c' => 'd'], SerializationContext::create()->setInitialType('array<string,string>')); // {"d" : "d"}