【问题标题】:How to serialize empty array to JSON object (curly braces) with JMS Serializer in Symfony如何在 Symfony 中使用 JMS 序列化器将空数组序列化为 JSON 对象(大括号)
【发布时间】:2017-05-26 02:35:35
【问题描述】:

具有以下 PHP 类

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": []}

【问题讨论】:

标签: php symfony serialization jmsserializerbundle jms-serializer


【解决方案1】:

正如@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 https://stackoverflow.com/q/41588574/878514
     */
    private function emptyArrayAsObject(array $array) {
        if (count($array) == 0) {
            return new \stdClass();
        }
        return $array;
    }
}

如果使用 Symfony,你需要register it

【讨论】:

    【解决方案2】:

    您可以通过在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"}
    

    【讨论】:

      猜你喜欢
      • 2021-11-16
      • 1970-01-01
      • 1970-01-01
      • 2014-01-28
      • 1970-01-01
      • 2018-02-13
      • 2021-05-29
      • 2022-01-04
      • 1970-01-01
      相关资源
      最近更新 更多