Skip to content

Commit 4528c11

Browse files
bug #36601 [Serializer] do not transform empty \Traversable to Array (soyuka)
This PR was merged into the 4.4 branch. Discussion ---------- [Serializer] do not transform empty \Traversable to Array | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tickets | na | License | MIT | Doc PR | na Today, using `PRESERVE_EMPTY_OBJECTS` ([introduced in 4.0](f28e826)), the JSON serialization of: ```php <?php $object = []; $object['foo'] = new \ArrayObject(); $object['bar'] = new \ArrayObject(['notempty']); $object['baz'] = new \ArrayObject(['nested' => new \ArrayObject()]); ``` Outputs: ```json {"foo":[],"bar":["notempty"],"baz":{"nested":[]}} ``` Instead of the expected: ```json {"foo":{},"bar":["notempty"],"baz":{"nested":{}}} ``` This issue comes from the Serializer that transforms `Traversable` to an Array [here](https://github.com/symfony/symfony/blob/11a707200d65d1142b681100fdfd5a9782f93f02/src/Symfony/Component/Serializer/Serializer.php#L159). Also, the `AbstractObjectNormalizer` [doesn't support Traversable](https://github.com/symfony/symfony/blob/11a707200d65d1142b681100fdfd5a9782f93f02/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php#L134), but he allows to preserve empty objects. I propose this patch where the fix doesn't transform a `Traversable` to an Array. I see another way to patch this in which we could allow empty Traversable in the `AbstractObjectNormalizer` (not sure it's better though). See attached [other-fix.patch](https://github.com/symfony/symfony/files/4539865/other-fix.log) to see the alternative patch. Commits ------- e5c2029 Fix serializer do not transform empty \Traversable to Array
2 parents c5e5b2d + e5c2029 commit 4528c11

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

src/Symfony/Component/Serializer/Serializer.php

+4
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ public function normalize($data, $format = null, array $context = [])
157157
}
158158

159159
if (\is_array($data) || $data instanceof \Traversable) {
160+
if ($data instanceof \Countable && 0 === $data->count()) {
161+
return $data;
162+
}
163+
160164
$normalized = [];
161165
foreach ($data as $key => $val) {
162166
$normalized[$key] = $this->normalize($val, $format, $context);

src/Symfony/Component/Serializer/Tests/SerializerTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
2626
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
2727
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
28+
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
2829
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
2930
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
3031
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
@@ -490,6 +491,26 @@ public function testNotNormalizableValueExceptionMessageForAResource()
490491
(new Serializer())->normalize(tmpfile());
491492
}
492493

494+
public function testNormalizePreserveEmptyArrayObject()
495+
{
496+
$serializer = new Serializer(
497+
[
498+
new PropertyNormalizer(),
499+
new ObjectNormalizer(),
500+
new ArrayDenormalizer(),
501+
],
502+
[
503+
'json' => new JsonEncoder(),
504+
]
505+
);
506+
507+
$object = [];
508+
$object['foo'] = new \ArrayObject();
509+
$object['bar'] = new \ArrayObject(['notempty']);
510+
$object['baz'] = new \ArrayObject(['nested' => new \ArrayObject()]);
511+
$this->assertEquals('{"foo":{},"bar":["notempty"],"baz":{"nested":{}}}', $serializer->serialize($object, 'json', [AbstractObjectNormalizer::PRESERVE_EMPTY_OBJECTS => true]));
512+
}
513+
493514
private function serializerWithClassDiscriminator()
494515
{
495516
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));

0 commit comments

Comments
 (0)