solophp / http-emitter
PSR-7 HTTP Response Emitter
v2.2.0
2026-10-16 19:47 UTC
Requires
- php: ^8.1
- psr/http-message: ^1.1|^2.0
- solophp/contracts: ^1.1
Requires (Dev)
- nyholm/psr7: ^1.8
- phpstan/phpstan: ^2.0.0
- phpunit/phpunit: ^10.5 || ^11.0 || ^12.0
- squizlabs/php_codesniffer: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
PSR-7 HTTP Response Emitter for PHP 8.1+. Implements Solo\Contracts\Http\EmitterInterface, so it plugs straight into solophp/application.
Installation
composer require solophp/http-emitter
Usage
use Solo\HttpEmitter\Emitter; $emitter = new Emitter(); $emitter->emit($response);
The body is streamed in chunks of 4096 bytes. Pass another size to the constructor if you need to:
$emitter = new Emitter(responseChunkSize: 65536);
With solophp/application
Register the emitter in a service provider:
use Solo\Contracts\Http\EmitterInterface; use Solo\HttpEmitter\Emitter; $container->set(EmitterInterface::class, fn() => new Emitter());
Application::run() resolves EmitterInterface from the container and emits the response returned by the middleware pipeline.
Behavior
- The status line is sent after the headers, so a
Locationheader can't reset the status code to302 - Repeated header values are sent as separate headers;
Set-Cookienever replaces cookies that were already set - Seekable bodies are rewound before output
- A valid
Content-Lengthheader limits how many body bytes are sent; otherwise the body is read to the end - No body is sent for
1xx,204,205and304responses - Output stops early if the client disconnects
- If headers were already sent, only the body is emitted
Production notes
- Keep
display_errorsoff. Any output beforeemit()(a warning, a BOM or blank line before<?php, a strayecho) makes PHP send its default headers early, and the emitter can then only send the body emit()runs after the middleware pipeline, so error-handling middleware doesn't see failures while the body is read. By then the headers are out; log such errors with a global exception handler- HEAD requests need no special handling: PHP drops the body of a HEAD response itself, including routes that fall back from HEAD to GET
- Bodies are sent in chunks, so memory use stays flat for large responses, unless
emit()runs inside anob_start()without a chunk size
Requirements
- PHP ^8.1
- PSR HTTP Message ^1.1|^2.0
- solophp/contracts ^1.1
Testing
# Code style, static analysis and tests composer check # Run tests composer test # Static analysis composer stan # Code style check composer cs # Code style fix composer cs-fix
License
MIT