Menu
Reference
Reader
final class Reader
A bounded, buffered read from a stream.
Reads go through a {@see ByteBuffer} that you supply and may share. Bytes pulled from the stream beyond what a read asked for stay in that buffer, so the next reader of the same buffer, for example the next request on a keep-alive connection, finds them there.
The limit given to the constructor is a byte budget. With a limit, the
Reader reports end of input once the budget is spent, whatever the stream
does afterwards; with the default of -1 it reads until the peer closes. A
read that finds nothing returns '': that means end of input, not an error,
and a short read only means that is what had arrived.
$buf = new Buffer\ByteBuffer();
$r = new Buffer\Reader($stream, $buf, 10);
$body = $r->readAll(1024);Example
// Buffer\Writer batches small writes; Buffer\Reader reads a bounded body and
// leaves whatever follows it in the shared buffer.
use Buffer\ByteBuffer;
use Buffer\Reader;
use Buffer\Writer;
$p = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);
$w = new Writer($p[0]);
$w->write("HELLO-");
$w->write("BODY");
echo "queued: ", $w->pending(), ", on the wire: ", $w->bytesWritten(), "\n";
$w->writev(["next-", "request"]); // flushes the queue, then one writev
echo "queued: ", $w->pending(), ", on the wire: ", $w->bytesWritten(), "\n";
fclose($p[0]); // the peer is done: reads now see EOF
// A Reader with a 10-byte budget; the buffer is shared with the next reader.
$buf = new ByteBuffer();
$r = new Reader($p[1], $buf, 10);
echo "remaining: ", $r->remaining(), "\n";
echo "read: ", $r->read(4), "\n";
echo "read: ", $r->read(100), "\n";
echo "budget spent: ", var_export($r->eof(), true), ", read '", $r->read(5), "'\n";
echo "left in buffer: ", $buf->view(), "\n";
// readAll() refuses more than its cap: '' and ->over, no exception.
$buf2 = new ByteBuffer();
$q = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);
fwrite($q[0], str_repeat("z", 100));
fclose($q[0]);
$r2 = new Reader($q[1], $buf2);
$all = $r2->readAll(50);
echo "readAll(50): ", strlen($all), " bytes, over=", var_export($r2->over, true), "\n";
fclose($p[1]);
fclose($q[1]);Output
queued: 10, on the wire: 0
queued: 0, on the wire: 22
remaining: 10
read: HELL
read: O-BODY
budget spent: true, read ''
left in buffer: next-request
readAll(50): 0 bytes, over=trueSee also: ByteBuffer, Writer
Properties
over | bool | True once a read could not complete because a cap was hit: readAll() refused a body bigger than its cap, or the shared buffer was full. |
over#source
bool $over = false
True once a read could not complete because a cap was hit: readAll() refused a body bigger than its cap, or the shared buffer was full. It is a flag and not an exception so a server can choose between answering 413 and carrying on.
Methods
__construct() | Create a reader. |
remaining() | The unspent part of the byte budget. |
eof() | Whether nothing more will come. |
bytesRead() | The total number of bytes returned by read() so far. |
read() | Read up to a number of bytes, waiting for the stream when the buffer is empty. |
readAll() | Read the rest of the input as one string, refusing to collect more than a cap. |
discard() | Read to the end of the input and throw the bytes away. |
__construct()#source
function __construct(\Resource $src, ByteBuffer $buf, int $limit = -1)
Create a reader.
Parameters
$src\Resource- the stream to read from
$bufByteBuffer- buffer to read through; pass the same one to successive readers of one stream, so surplus bytes are not lost
$limitint = -1- byte budget, or -1 to read until the peer closes
remaining()#source
function remaining(): int
The unspent part of the byte budget.
Returns
int — bytes left, or -1 when the reader has no limit
eof()#source
function eof(): bool
Whether nothing more will come.
Returns
bool — true when the budget is spent, or the peer has closed and the buffer is drained, or the shared buffer overflowed and is drained
bytesRead()#source
function bytesRead(): int
The total number of bytes returned by read() so far.
Returns
int — the byte count
read()#source
function read(int $max): string
Read up to a number of bytes, waiting for the stream when the buffer is empty.
Parameters
$maxint- most bytes to return; never more than the budget has left
Returns
string — the bytes; '' means end of input (budget spent or peer closed), not an error. A short result is ordinary and means only that this is what had arrived.
readAll()#source
function readAll(int $cap): string
Read the rest of the input as one string, refusing to collect more than a cap.
On overflow it returns '' and sets {@see $over}, instead of throwing.
Parameters
$capint- most bytes to accept in total
Returns
string — everything up to end of input, or '' when it exceeded $cap
discard()#source
function discard(): int
Read to the end of the input and throw the bytes away.
Use it to skip an unwanted body so the stream is positioned at whatever follows.
Returns
int — how many bytes were dropped