如何使用 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"}