Десериализовать значение смешанного типа с помощью JMS Serializer

У меня проблемы с JMS Serializer — мне нужно десериализовать грязный JSON со смешанным типом для значения score. Например:

{ label: "hello", score: 50 }

Or

{ label: "hello", score: true }

Если я поставлю @Type("int"), когда значение равно boolean, оно будет десериализовано как 1 или 0...
Я хотел бы получить 100, когда значение равно true, и 0, если значение равно false.
Как можно Я управляю этим смешанным типом при десериализации?

Мои занятия:

class Lorem 
{
    /**
     * @Type("string")
     * @SerializedName("label")
     * @var string
     */
    protected $label;

    /**
     * @Type("int")
     * @SerializedName("score")
     * @var int
     */
    protected $score;
}

person HanXHX    schedule 08.04.2018    source источник


Ответы (2)


Вы можете написать свой пользовательский обработчик, определяющий новый my_custom_type (или что-то с более подходящим названием :), которые вы затем можете использовать в своих аннотациях.

Что-то вроде этого должно работать:

class MyCustomTypeHandler implements SubscribingHandlerInterface 
{
    /**
     * {@inheritdoc}
     */
    public static function getSubscribingMethods()
    {
        return [
            [
                'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
                'format' => 'json',
                'type' => 'my_custom_type',
                'method' => 'deserializeFromJSON',
            ],
        ];
    }

    /**
     * The de-serialization function, which will return always an integer.
     *
     * @param JsonDeserializationVisitor $visitor
     * @param int|bool $data
     * @param array $type
     * @return int
     */
    public function deserializeFromJSON(JsonDeserializationVisitor $visitor, $data, array $type)
    {
        if ($data === true) {
            return 100;
        }
        if ($data === false) {
            return 0;
        }
        return $data;
    }
}
person MikO    schedule 08.04.2018

Type annotation будет приводить значение. Возможно, вы можете определить массив Type, см. doc что-то в этом роде Type("array<string>,array< boolean>")

person Smaïne    schedule 08.04.2018
comment
Аннотация Type не допускает такой синтаксис. - person ironchicken; 22.08.2019