Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6e42b36

Browse files
bug #61561 [JsonStreamer] Fix decoding iterable lists (mtarld)
This PR was merged into the 7.3 branch. Discussion ---------- [JsonStreamer] Fix decoding iterable lists | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | Fix #61559 | License | MIT Because a `list<T>` is a subtype of `array<T>`, an `iterable<T>` cannot be a list. This means that, as said [here](#59308 (comment)): > There is no way to be sure that keys of an iterable are successive (even if they are integers). > And if keys are not successive, the resulting JSON structure is an object and not an array. > According, to the [JSON specification](https://datatracker.ietf.org/doc/html/rfc8259#section-4), object' keys must be strings, and not integers. This imply that it is right now impossible to "yield" items from `[{"itemId": 1, "modificationDate": "2025-10-10"}]` - it can only be yielded from `{"0": {"itemId": 1, "modificationDate": "2025-10-10"}}`. I think that in the real world, a lot of people want to be able to yield items from `[...]`, even though it does not stick with the JSON specification. This PR is doing the trade-off of considering `iterable<int, Anything>` as an "iterable list" (like `list<Anything>` but not cast to array). Commits ------- 2b9b801 [JsonStreamer] Fix decoding iterable lists
2 parents 9d93fb4 + 2b9b801 commit 6e42b36

File tree

2 files changed

+4
-2
lines changed

2 files changed

+4
-2
lines changed

src/Symfony/Component/JsonStreamer/Read/PhpAstBuilder.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,10 +379,12 @@ private function buildCollectionNodeStatements(CollectionNode $node, bool $decod
379379
? $this->builder->funcCall($this->builder->var('iterable'), [$this->builder->var('stream'), $this->builder->var('data')])
380380
: $this->builder->funcCall($this->builder->var('iterable'), [$this->builder->var('data')]);
381381

382+
$collectionKeyType = $node->getType()->getCollectionKeyType();
383+
382384
$prepareDataStmts = $decodeFromStream ? [
383385
new Expression(new Assign($this->builder->var('data'), $this->builder->staticCall(
384386
new FullyQualified(Splitter::class),
385-
$node->getType()->isList() ? 'splitList' : 'splitDict',
387+
($collectionKeyType instanceof BuiltinType && TypeIdentifier::INT === $collectionKeyType->getTypeIdentifier()) ? 'splitList' : 'splitDict',
386388
[$this->builder->var('stream'), $this->builder->var('offset'), $this->builder->var('length')],
387389
))),
388390
] : [];

src/Symfony/Component/JsonStreamer/Tests/JsonStreamReaderTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public function testReadCollection()
8787
$this->assertRead($reader, function (mixed $read) {
8888
$this->assertIsIterable($read);
8989
$this->assertSame([true, false], iterator_to_array($read));
90-
}, '{"0": true, "1": false}', Type::iterable(Type::bool(), Type::int()));
90+
}, '[true, false]', Type::iterable(Type::bool(), Type::int()));
9191
}
9292

9393
public function testReadObject()

0 commit comments

Comments
 (0)