amphp/byte-stream
Event-driven byte stream abstractions for PHP 8.1+ in the AMPHP ecosystem. Provides ReadableStream/WritableStream interfaces plus implementations like Payload, buffers, resource/iterable streams, stream chaining, base64 encode/decode, and decompression for fiber-friendly I/O.
Start by installing the package via Composer:
composer require amphp/byte-stream
Then, familiarize yourself with the two core interfaces: Amp\ByteStream\ReadableStream and Amp\ByteStream\WritableStream. The simplest first use case is wrapping a socket resource (e.g., from stream_socket_client()) with the provided ResourceStream adapter to convert it into a non-blocking stream:
use Amp\ByteStream\ResourceStream;
use Amp\Loop;
Loop::run(function () {
$socket = stream_socket_client('tcp://example.com:80');
$stream = new ResourceStream($socket);
// Write request
yield $stream->write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n");
// Read response in chunks
while ($chunk = yield $stream->read()) {
echo $chunk;
}
});
Check the examples/ directory in the repo for minimal working demos.
BufferedStream to decouple reader/writer rates and avoid partial reads/writes:
use Amp\ByteStream\BufferedStream;
$buffered = new BufferedStream($underlyingStream);
$data = yield $buffered->read(); // Reads full chunks or buffers until delimiter
onOverrun()/onUnderrun() callbacks when building custom writable streams (e.g., a rate-limited HTTP client sink).$pipeline = (new Pipeline())
->pipe(new Filter\HexDecode())
->pipe(new Filter\Gunzip());
yield $pipeline->write($hexEncodedGzip);
ResourceStream for raw socket I/O, and Pipe to proxy data between client/server streams in reverse proxies or HTTP/2 gateways.fopen() handles with ResourceStream for non-blocking file reads/writes inside Loop::run() contexts.BufferedStream usage—pair with LimitStream or manual backpressure signaling to prevent OOM in high-throughput systems.read() returns null on EOF, not ''. Always check: if ($chunk === null) { break; }.close() in finally blocks—PHP’s GC may not promptly release underlying resources.ResourceStream for pipes/stdin/stdout may block on non-blocking streams if not properly set via stream_set_blocking(false). Always validate.ReadableStreamInterface/WritableStreamInterface carefully—ensure cancel() terminates pending operations cleanly to prevent leaks.CallableStream or InMemoryStream (if available in your version) for predictable unit tests without sockets/files.How can I help you explore Laravel packages today?