Skip to content

Commit 36c8cb7

Browse files
committed
[HttpFoundation] Support iterable of string in StreamedResponse
1 parent 8c841e3 commit 36c8cb7

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

src/Symfony/Component/HttpFoundation/CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.3
5+
---
6+
7+
* Add support for iterable of string in `StreamedResponse`
8+
49
7.2
510
---
611

@@ -40,7 +45,7 @@ CHANGELOG
4045
* Add `UriSigner` from the HttpKernel component
4146
* Add `partitioned` flag to `Cookie` (CHIPS Cookie)
4247
* Add argument `bool $flush = true` to `Response::send()`
43-
* Make `MongoDbSessionHandler` instantiable with the mongodb extension directly
48+
* Make `MongoDbSessionHandler` instantiable with the mongodb extension directly
4449

4550
6.3
4651
---

src/Symfony/Component/HttpFoundation/StreamedResponse.php

+22-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
/**
1515
* StreamedResponse represents a streamed HTTP response.
1616
*
17-
* A StreamedResponse uses a callback for its content.
17+
* A StreamedResponse uses a callback or an iterable of strings for its content.
1818
*
1919
* The callback should use the standard PHP functions like echo
2020
* to stream the response back to the client. The flush() function
@@ -32,19 +32,36 @@ class StreamedResponse extends Response
3232
private bool $headersSent = false;
3333

3434
/**
35-
* @param int $status The HTTP status code (200 "OK" by default)
35+
* @param callable|iterable<string>|null $callbackOrChunks
36+
* @param int $status The HTTP status code (200 "OK" by default)
3637
*/
37-
public function __construct(?callable $callback = null, int $status = 200, array $headers = [])
38+
public function __construct(callable|iterable|null $callbackOrChunks = null, int $status = 200, array $headers = [])
3839
{
3940
parent::__construct(null, $status, $headers);
4041

41-
if (null !== $callback) {
42-
$this->setCallback($callback);
42+
if (\is_callable($callbackOrChunks)) {
43+
$this->setCallback($callbackOrChunks);
44+
} elseif (null !== $callbackOrChunks) {
45+
$this->setChunks($callbackOrChunks);
4346
}
4447
$this->streamed = false;
4548
$this->headersSent = false;
4649
}
4750

51+
/**
52+
* @param iterable<string> $chunks
53+
*/
54+
public function setChunks(iterable $chunks): static
55+
{
56+
$this->callback = static function () use ($chunks): void {
57+
foreach ($chunks as $chunk) {
58+
echo $chunk;
59+
}
60+
};
61+
62+
return $this;
63+
}
64+
4865
/**
4966
* Sets the PHP callback associated with this Response.
5067
*

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

+11
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ public function testConstructor()
2525
$this->assertEquals('text/plain', $response->headers->get('Content-Type'));
2626
}
2727

28+
public function testConstructorWithChunks()
29+
{
30+
$chunks = ['foo', 'bar', 'baz'];
31+
$callback = (new StreamedResponse($chunks))->getCallback();
32+
33+
ob_start();
34+
$callback();
35+
36+
$this->assertSame('foobarbaz', ob_get_clean());
37+
}
38+
2839
public function testPrepareWith11Protocol()
2940
{
3041
$response = new StreamedResponse(function () { echo 'foo'; });

0 commit comments

Comments
 (0)