Menu

Reference / Buffer

Writer

finalclass
final class Writer

Buffered writes to a stream, with a vectored form.

write() queues bytes and sends them once the queue reaches a threshold, so output assembled from many small pieces costs a few system calls instead of one per piece. Call flush() at the end: bytes still queued are not written for you.

$w = new Buffer\Writer($stream);
$w->write("HTTP/1.1 200 OK\r\n\r\n");
$w->write($body);
$w->flush();

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=true

See also: Reader, ByteBuffer

Methods

__construct()Create a writer.
write()Queue bytes, sending the whole queue once it reaches the flush threshold.
writev()Send several strings in one vectored write.
flush()Send everything queued to the stream.
bytesWritten()The number of bytes handed to the stream so far.
pending()The number of bytes queued and not yet sent.

__construct()#source

function __construct(\Resource $dst, int $flushAt = 65536)

Create a writer.

Parameters

$dst \Resource
the stream to write to
$flushAt int = 65536
queue size in bytes at which write() sends automatically (default 65536)

write()#source

function write(string $s): void

Queue bytes, sending the whole queue once it reaches the flush threshold. An empty string does nothing.

Parameters

$s string
the bytes to write

writev()#source

function writev(array<int,string> $parts): int

Send several strings in one vectored write.

Anything already queued is flushed first. The pieces go to the stream without being joined in userspace, which keeps a head-plus-body response to a single system call.

Parameters

$parts array<int,string>
the strings to write, in order

Returns

int — the number of bytes the stream accepted

flush()#source

function flush(): void

Send everything queued to the stream. Does nothing when the queue is empty.

bytesWritten()#source

function bytesWritten(): int

The number of bytes handed to the stream so far. Bytes still queued are not counted.

Returns

int — the byte count

pending()#source

function pending(): int

The number of bytes queued and not yet sent.

Returns

int — the byte count

View source