Stream Response
Normally, resources are rendered by renderers into one string and finally echo
ed out, but then you cannot output content whose size exceeds the memory limit of PHP. With StreamRenderer
you can stream HTTP output and you can output large size content while keeping memory consumption low. Stream output can also be used in coexistence with existing renderers.
Change Transferer and Renderer
Use the StreamTransferInject trait on the page to render and respond to the stream output. In the example of this download page, since $body
is made to be a resource variable of the stream, the injected renderer is ignored and the resource is streamed.
use BEAR\Streamer\StreamTransferInject;
class Download extends ResourceObject
{
use StreamTransferInject;
public $headers = [
'Content-Type' => 'image/jpeg',
'Content-Disposition' => 'attachment; filename="image.jpg"'
];
public function onGet(): static
{
$fp = fopen(__DIR__ . '/BEAR.jpg', 'r');
$this->body = $fp;
return $this;
}
}
With Renderers
Stream output can coexist with conventional renderers. Normally, Twig renderers and JSON renderers generate character strings, but when a stream is assigned to a part of it, the whole is output as a stream.
This is an example of assigning a string
and a resource
variable to the Twig template and generating a page of inline image.
Template
<!DOCTYPE html>
<html lang="en">
<body>
<p>Hello, {{ name }}</p>
<img src="data:image/jpg;base64,{{ image }}">
</body>
</html>
name
assigns the string as usual, but assigns the resource variable of the image file’s pointer resource to image
with the base64-encode
filter.
class Image extends ResourceObject
{
use StreamTransferInject;
public function onGet(string $name = 'inline image'): static
{
$fp = fopen(__DIR__ . '/image.jpg', 'r');
stream_filter_append($fp, 'convert.base64-encode'); // image base64 format
$this->body = [
'name' => $name,
'image' => $fp
];
return $this;
}
}
If you want to further control streaming such as streaming bandwidth and timing control, uploading to the cloud, etc use StreamResponder which is build for it.
The demo is available at MyVendor.Stream.
This document needs to be proofread by native speaker.