JMS Serializer is perhaps my favorite and most frequently used open source package, and I am infinitely thankful for Johannes Schmitt for his contribution.

However, with heavy usage of Annotations JMS can become frustrating at times. Especially when building API data that you’re expecting to be formatted as an array or object and standardizing the behavior.

With the use of @MaxDepth, you’ll find that your recursive entity serialization may end up serialized as an object of nested objects, instead of an array of objects as you expect.

Check this issue for a deeper discussion on variations of the same problem, and also the solution implemented here.

Expected

[
  {'id':1},
  {'id':2}
]

Actual

{
  0: {'id':1}
  1: {'id':2}
}

The fix for this is actually quite simple:

JsonSerializationVisitor.php

<?php

namespace Your\Namespace\Here;

/**
 * Class JsonSerializationVisitor
 *
 * @package Camelot\Bundle\CoreBundle\Services
 */
class JsonSerializationVisitor extends \JMS\Serializer\JsonSerializationVisitor
{
    public function getResult()
    {
        //EXPLICITLY CAST TO ARRAY
        $result = @json_encode((array) $this->getRoot(), $this->getOptions());

        switch (json_last_error()) {
            case JSON_ERROR_NONE:
                return $result;

            case JSON_ERROR_UTF8:
                throw new \RuntimeException('Your data could not be encoded because it contains invalid UTF8 characters.');

            default:
                throw new \RuntimeException(sprintf('An error occurred while encoding your data (error code %d).', json_last_error()));
        }
    }
}

parameters.yml

jms_serializer.json_serialization_visitor.class: Path\To\JsonSerializationVisitor

 

Categories: Random

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *