Search code examples
phpsymfonyjms-serializer

Deserialize value of mixed type with JMS Serializer


I have some trouble with JMS Serializer - I need to deserialize a dirty JSON with a mixed type for the score value. For example:

{ label: "hello", score: 50 }

Or

{ label: "hello", score: true }

If I put @Type("int"), when the value is a boolean, it gets deserialized as 1 or 0...
I would like to get 100 when the value is true, and 0 when the value is false.
How could I manage this mixed type on deserialization?

My class:

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

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

Solution

  • You can write your custom handler defining a new my_custom_type (or something better named :), which you can then use in your annotations.

    Something like this should work:

    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;
        }
    }