ResponseEmitter
Emits a PSR-7 response to the SAPI, streaming it when the body is a {@see CallbackStream} (greenhouse evidence/0472). A front controller used to hand-roll `http_response_code(...)`, a `header()` loop, and `echo $response->getBody()`. That last step materializes the whole body — fine for a page, fatal for a live feed, because nothing reaches the client until the response is complete. This emitter replaces that tail: it sends the status and headers, then, if the body is a {@see CallbackStream}, runs the callback (which writes and flushes over the life of the connection) INSTEAD of stringifying it. Every ordinary response takes the same buffered `echo (string) $body` path as before, so adopting the emitter is behavior -preserving; streaming is the new capability a `CallbackStream` body opts into. The status and header sinks — and, for streaming, the buffer flusher — are injectable so emission is testable without a live SAPI (the defaults are PHP's own `http_response_code()` and `header()`, matching the front controller this replaces — multiple values of one header are appended, not replaced). Streaming a {@see CallbackStream} first defeats PHP's output buffering: without ending any active output buffer, `flush()` inside the callback cannot push bytes to the client, so the "stream" would arrive whole at connection close — no streaming at all. Ending output buffers is a SAPI-emission concern, so it lives here (not in every streaming handler), and it is injectable so a test can capture the streamed bytes in its own buffer instead of having them flushed away.
ResponseEmitter::__construct()
public function __construct(?callable $statusSink = null, ?callable $headerSink = null, ?callable $bufferFlusher = null):Parameters
| Name | Type | Description |
|---|---|---|
| $statusSink | (callable(int): void | null) | Receives the status code (default: `http_response_code`). |
| $headerSink | (callable(string): void | null) | Receives each `"Name: value"` line (default: `header(..., false)`). |
| $bufferFlusher | (callable(): void | null) | Ends active output buffers before streaming (default: `ob_end_flush` down to level 0); a test passes a no-op to keep its capture buffer. |
ResponseEmitter::emit()
public function emit(Psr\Http\Message\ResponseInterface $response): voidSend the response: status, headers, then the body — streamed if it is a {@see CallbackStream}.
Parameters
| Name | Type | Description |
|---|---|---|
| $response | Psr\Http\Message\ResponseInterface |