10000 [HttpFoundation] Add `StreamedResponse::createFromTempFile()` · symfony/symfony@0c52104 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0c52104

Browse files
[HttpFoundation] Add StreamedResponse::createFromTempFile()
1 parent b497938 commit 0c52104

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

src/Symfony/Component/HttpFoundation/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* Add `ParameterBag::getEnum()`
88
* Create migration for session table when pdo handler is used
99
* Add support for Relay PHP extension for Redis
10+
* Add `StreamedResponse::createFromTempFile()`
1011

1112
6.2
1213
---

src/Symfony/Component/HttpFoundation/StreamedResponse.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class StreamedResponse extends Response
2929
protected $callback;
3030
protected $streamed;
3131
private bool $headersSent;
32+
private static int $chunkSize = 8 * 1024;
3233

3334
/**
3435
* @param int $status The HTTP status code (200 "OK" by default)
@@ -114,4 +115,29 @@ public function getContent(): string|false
114115
{
115116
return false;
116117
}
118+
119+
public static function createFromTempFile(\SplTempFileObject $file, int $status = 200, array $headers = [], int $chunkSize = null): static
120+
{
121+
if (null !== $chunkSize && 1 > $chunkSize) {
122+
throw new \InvalidArgumentException(sprintf('Chunk size of streamed response from a temporary file must be at least 1, got %d.', $chunkSize));
123+
}
124+
125+
return new self(static function () use ($file, $chunkSize) {
126+
$out = fopen('php://output', 'w');
127+
128+
ignore_user_abort(true);
129+
130+
$file->rewind();
131+
while (!$file->eof()) {
132+
fwrite($out, $file->fread($chunkSize ?? static::$chunkSize));
133+
flush();
134+
135+
if (connection_aborted()) {
136+
break;
137+
}
138+
}
139+
140+
fclose($out);
141+
}, $status, $headers);
142+
}
117143
}

src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,29 @@ public function testSetNotModified()
129129
$string = ob_get_clean();
130130
$this->assertEmpty($string);
131131
}
132+
133+
public function testCreateFromTemporaryFileInvalidChunkSize()
134+
{
135+
$this->expectException(\InvalidArgumentException::class);
136+
$this->expectExceptionMessage('Chunk size of streamed response from a temporary file must be at least 1, got -10.');
137+
StreamedResponse::createFromTempFile(new \SplTempFileObject(), chunkSize: -10);
138+
}
139+
140+
public function testCreateFromTemporaryFile()
141+
{
142+
$file = new \SplTempFileObject();
143+
$file->fwrite('foo,bar');
144+
145+
$response = StreamedResponse::createFromTempFile($file, 201, [
146+
'Content-Type' => 'text/csv',
147+
]);
148+
149+
$this->assertSame(201, $response->getStatusCode());
150+
$this->assertSame('text/csv', $response->headers->get('Content-Type'));
151+
152+
ob_start();
153+
$response->sendContent();
154+
$string = ob_get_clean();
155+
$this->assertSame('foo,bar', $string);
156+
}
132157
}

0 commit comments

Comments
 (0)
0