From a22b27315a146727df1a4b755caefc60abca8d2e Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 11 Sep 2017 15:25:37 -0500 Subject: [PATCH] Updates documentation of emitters - Ensures they do not discuss output buffering. - Adds section on `SapiStreamEmitter`. --- doc/book/emitting-responses.md | 53 +++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/doc/book/emitting-responses.md b/doc/book/emitting-responses.md index 7715601a..897b64ae 100644 --- a/doc/book/emitting-responses.md +++ b/doc/book/emitting-responses.md @@ -3,10 +3,15 @@ If you are using a non-SAPI PHP implementation and wish to use the `Server` class, or if you do not want to use the `Server` implementation but want to emit a response, this package provides an interface, `Zend\Diactoros\Response\EmitterInterface`, defining a method `emit()` for emitting the -response. A single implementation is currently available, `Zend\Diactoros\Response\SapiEmitter`, -which will use the native PHP functions `header()` and `echo` in order to emit the response. If you -are using a non-SAPI implementation, you will need to create your own `EmitterInterface` -implementation. +response. + +Diactoros provides two implementations currently, both for working with +traditional Server API (SAPI) implementations: `Zend\Diactoros\Response\SapiEmitter` +and `Zend\Diactoros\Response\SapiStreamEmitter`. Each uses the native `header()` +PHP function to emit headers, and `echo()` to emit the response body. + +If you are using a non-SAPI implementation, you will need to create your own +`EmitterInterface` implementation. For example, the `SapiEmitter` implementation of the `EmitterInterface` can be used thus: @@ -16,3 +21,43 @@ $response->getBody()->write("some content\n"); $emitter = new Zend\Diactoros\Response\SapiEmitter(); $emitter->emit($response); ``` + +## Emitting ranges of streamed files + +The `SapiStreamEmitter` is useful when you want to emit a `Content-Range`. As an +example, to stream a range of bytes from a file to a client, the client can pass +the following header: + +```http +Range: bytes=1024-2047 +``` + +Your application would then populate the response with a `Content-Range` header: + +```php +$range = $request->getHeaderLine('range'); +$range = str_replace('=', ' ', $range); + +$body = new Stream($pathToFile); +$size = $body->getSize(); +$range .= '/' . $size; + +$response = new Response($body); +$response = $response->withHeader('Content-Range', $range); +``` + +> Note: you will likely want to ensure the range specified falls within the +> content size of the streamed body! + +The `SapiStreamEmitter` detects the `Content-Range` header and emits only the +bytes specified. + +```php +$emitter = new SapiStreamEmitter(); +$emitter->emit($response); +``` + +The `SapiStreamEmitter` may be used in place of the `SapiEmitter`, even when not +sending files. However, unlike the `SapiEmitter`, it will emit a chunk of +content at a time instead of the full content at once, which could lead to +performance overhead. The default chunk size is 8192 bytes.