Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1fb9d17

Browse files
committed
bug#60260 [Serializer] PreventCannot traverse an already closed generator error by materializing Traversable input (santysisi)
This PR was merged into the 6.4 branch.Discussion----------[Serializer] Prevent `Cannot traverse an already closed generator` error by materializing Traversable input| Q | A| ------------- | ---| Branch? | 6.4| Bug fix? | yes| New feature? | no| Deprecations? | no| Issues |Fix#60141| License | MIT### ✅ Pull Request description:This PR addresses the issue reported in the linked ticket, specifically the error:`Cannot traverse an already closed generator`The fix involves converting `Traversable` input into an array using `iterator_to_array($data)`, in order to allow multiple traversals of generator-based inputs.At first glance, it might seem that this approach significantly increases memory usage, since all generator values are stored in memory. However, this is not the case. In the current logic, the following [loop](https://github.com/symfony/symfony/blob/6.4/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php#L82-L86) already forces all values from the generator into memory:```phpforeach ($data as &$value) { $flattened = []; $this->flatten($value, $flattened, $keySeparator, '', $escapeFormulas); $value = $flattened;}```Therefore, materializing the generator with `iterator_to_array() `does not increase peak memory usage in any meaningful way.As an example, here's the comparison of peak memory usage (measured with [memory_get_peak_usage](https://www.php.net/manual/en/function.memory-get-peak-usage.php)) when processing an array of 1 million integers:* **With the fix**: 90,044,272 bytes* **Without the fix**: 89,936,680 bytesThe difference is negligible, confirming that the fix does not introduce a meaningful performance cost in terms of memory.Commits-------c7206a9 Fix: prevent "Cannot traverse an already closed generator" error by materializing Traversable input
2 parentsebb9e65 +c7206a9 commit1fb9d17

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

‎src/Symfony/Component/Serializer/Encoder/CsvEncoder.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ public function encode(mixed $data, string $format, array $context = []): string
6565
}elseif (empty($data)) {
6666
$data = [[]];
6767
}else {
68+
if ($datainstanceof \Traversable) {
69+
// Generators can only be iterated once — convert to array to allow multiple traversals
70+
$data =iterator_to_array($data);
71+
}
6872
// Sequential arrays of arrays are considered as collections
6973
$i =0;
7074
foreach ($dataas$key =>$value) {

‎src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,4 +710,28 @@ public function testEndOfLinePassedInConstructor()
710710
$encoder =newCsvEncoder([CsvEncoder::END_OF_LINE =>"\r\n"]);
711711
$this->assertSame("foo,bar\r\nhello,test\r\n",$encoder->encode($value,'csv'));
712712
}
713+
714+
/** @dataProvider provideIterable */
715+
publicfunctiontestIterable(mixed$data)
716+
{
717+
$this->assertEquals(<<<'CSV'
718+
foo,bar
719+
hello,"hey ho"
720+
hi,"let's go"
721+
722+
CSV,$this->encoder->encode($data,'csv'));
723+
}
724+
725+
publicstaticfunctionprovideIterable()
726+
{
727+
$data = [
728+
['foo' =>'hello','bar' =>'hey ho'],
729+
['foo' =>'hi','bar' =>'let\'s go'],
730+
];
731+
732+
yield'array' => [$data];
733+
yield'array iterator' => [new \ArrayIterator($data)];
734+
yield'iterator aggregate' => [new \IteratorIterator(new \ArrayIterator($data))];
735+
yield'generator' => [(fn ():\Generator =>yieldfrom$data)()];
736+
}
713737
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp