Streams
Dirthara\Http\Stream wraps a PHP stream resource and is the body of every message. Create one with the
stream factory, or wrap a resource you already have:
use Dirthara\Http\Stream;
$resource = fopen('php://temp', 'r+b');
$stream = new Stream($resource);
Anything other than a stream resource throws InvalidStreamException::invalidResource().
Unlike messages, a stream is not immutable. Writing to it, reading from it, and seeking change the stream, and every message that holds it sees the change.
Capabilities
What a stream can do follows from the mode its resource was opened with.
| Method | True when |
|---|---|
isReadable() | The mode starts with r or contains +. |
isWritable() | The mode starts with w, a, x, or c, or contains +. |
isSeekable() | PHP reports the resource as seekable. |
All three return false once the stream is detached or closed.
Operations
| Method | Behavior |
|---|---|
read($length) | Read up to $length bytes, and at most 1 MiB per call. read(0) returns ''. |
getContents() | Read everything from the current position to the end. |
write($string) | Write at the current position and return the number of bytes written. |
tell() | The current position. |
seek($offset, $whence) | Move the position, with SEEK_SET, SEEK_CUR, or SEEK_END. |
rewind() | Move to the start. |
eof() | Whether the end has been reached. true once detached. |
getSize() | The size in bytes, or null when it is unknown or the stream is detached. |
getMetadata($key) | All metadata from stream_get_meta_data(), or one entry, or null for a missing key. |
detach() | Return the resource and leave the stream unusable, without closing it. |
close() | Detach the resource and close it. |
(string) $stream | Rewind when seekable and return everything, or '' when reading fails. |
Converting a stream to a string never throws, as PHP requires, so it returns '' both for an empty stream and for one
that failed. Use getContents() when a failure must surface.
Failures
| Situation | Exception |
|---|---|
| Reading from a stream that is not readable, or a failed read | StreamException::notReadable() |
| Writing to a stream that is not writable, or a failed write | StreamException::notWritable() |
| Seeking in a stream that is not seekable | StreamException::notSeekable() |
| A seek PHP refuses | StreamException::unableToSeek() |
| A position PHP cannot report | StreamException::unableToTell() |
| Any operation on a detached or closed stream, except those that report it | StreamException::detached() |
| A negative read length | InvalidStreamException::invalidReadLength() |
StreamException extends RuntimeException, as PSR-7 requires of these methods, so a catch (\RuntimeException)
written against the interface catches every failure of a stream operation. Only a negative read length, a mistake in the
call rather than a failure of the stream, is an InvalidArgumentException.
The 1 MiB limit on read() exists because PHP allocates the whole requested length before reading, so a length taken
from untrusted input could otherwise exhaust memory. Returning fewer bytes than asked is allowed; call read() again,
or use getContents(), for more.