zbateson/stream-decorators
Lightweight PHP stream decorators for composing and filtering streams. Wrap any resource to add behaviors like buffering, limiting, logging, or on-the-fly transforms while keeping a standard stream interface. Useful for email parsing, I/O pipelines, and testing.
Start by installing via Composer (composer require zbateson/stream-decorators), then identify a concrete use case—e.g., rate-limiting uploads or trimming output before writing to a log. Begin with one of the included decorators like LimitStream or BufferStream. The easiest first step: wrap a file stream to read only the first N bytes:
use ZBateson\StreamDecorators\LimitStream;
$stream = fopen('php://temp', 'r+');
fwrite($stream, 'Hello, this is a test string.');
rewind($stream);
$limited = new LimitStream($stream, 5); // Read only 5 bytes
echo stream_get_contents($limited); // Outputs: Hello
Check the src/ directory for decorator classes and read README.md (if present) for the most common patterns and constructor signatures.
new LoggingStream(new LimitStream($base, 1024))). Each decorator wraps another stream, preserving StreamInterface semantics.TrimStream to normalize input before processing (e.g., for CSV parsing or webhook payload handling).php://stdin with BufferStream to avoid partial reads, or apply ChunkStream for streaming large files without memory exhaustion.php://memory streams in unit tests to assert exact read/write behavior without file I/O.ResponseFactory output) with RateLimitStream to enforce throughput caps before sending responses.LimitStream and SeekableStream may alter ftell() behavior—always verify stream position after operations, especially when seeking or wrapping non-seekable streams (e.g., php://input).stream_set_timeout(), stream_context_get()) fall back to the underlying stream. Test edge cases with context-aware operations.StreamInterface or valid resource. Passing null or invalid streams causes silent failures—validate wrapped streams first.BufferStream) trade memory for throughput—avoid wrapping huge streams in memory buffers in production unless necessary.StreamDecoratorTrait and implement only the methods you need (e.g., read(), write()) rather than reinventing StreamInterface.LimitStream’s behavior is undefined when seeking before the current position on non-seekable streams—plan fallbacks (e.g., discard via read() instead of seek()).How can I help you explore Laravel packages today?