haphpiness

These are things in PHP which make me genuinely_happy();

Stream Wrappers & php:// — Virtual File Handles

PHP's stream system lets you treat memory, network connections, compression filters, and custom protocols as ordinary file handles. The built-in php:// wrappers are especially useful.

// php://memory — a file handle backed by RAM, not disk
$handle = fopen('php://memory', 'r+');
fwrite($handle, "line one\n");
fwrite($handle, "line two\n");

rewind($handle);
echo stream_get_contents($handle);  // "line one\nline two\n"
fclose($handle);

// Works with all standard file functions:
rewind($handle);
while (($line = fgets($handle)) !== false) {
    echo trim($line);
}

php://temp works like php://memory but transparently spills to a temporary file if the data exceeds a threshold (default 2 MB) — the right default for processing uploads or large responses:

$handle = fopen('php://temp/maxmemory:5242880', 'r+');  // 5 MB threshold
// Use it like any file handle; PHP handles the memory/disk decision

Other built-in wrappers: php://stdin, php://stdout, php://stderr for CLI pipes; compress.zlib://file.gz to read gzipped files transparently; data:// for inline data URIs. You can also register your own stream wrapper with stream_wrapper_register() to implement custom protocols.

// Use php://memory to test I/O code without touching the filesystem
function writeCsv(iterable $rows, $handle): void
{
    foreach ($rows as $row) {
        fputcsv($handle, $row);
    }
}

// In tests — no temp files, no cleanup, runs in microseconds
$out = fopen('php://memory', 'r+');
writeCsv([['a', 'b'], ['c', 'd']], $out);
rewind($out);
$result = stream_get_contents($out);
assert($result === "a,b\nc,d\n");

Significance: Testability

php://memory is the cleanest way to unit-test I/O code in PHP. Any function that accepts a file handle can be tested without touching the disk, without mock objects, and without temporary files to clean up. It's duck-typing for streams.