W3docs

PHP Stream

Streams are a powerful feature in PHP that allows developers to read and write data from a variety of sources, including files, sockets, and HTTP requests. The

PHP Streams

A stream in PHP is a generic way to read from or write to a flow of data, regardless of where that data lives. A file on disk, a chunk of memory, a network socket, and the body of an HTTP response are all very different things, yet PHP lets you handle them with the same set of functions. That uniformity is the whole point: once you know how to read a file with fopen()/fgets(), you already know how to read a web page or a memory buffer.

This page covers what streams are, the functions that drive them, the wrappers that identify a stream's source, and how to work with them safely.

What problem do streams solve?

Without streams you would need a different API for every data source — one for files, another for HTTP, another for sockets. Streams give you a single abstraction:

  • Wrapper — a prefix like file://, php://, http://, or php://memory that tells PHP what kind of resource you are addressing.
  • Resource handle — the value fopen() returns; you pass it to every other stream function.
  • Filters and contexts — optional layers that transform data (e.g. gzip) or configure the connection (e.g. HTTP headers, timeouts).

Because of this design, you can swap a local path for a remote URL and most of your code stays the same.

Core stream functions

These functions form the backbone of the Streams API:

FunctionWhat it does
fopen($target, $mode)Opens a file or URL and returns a stream resource (or false on failure).
fread($handle, $length)Reads up to $length bytes.
fgets($handle)Reads one line.
fwrite($handle, $string)Writes a string and returns the number of bytes written.
feof($handle)Returns true once the end of the stream is reached.
fclose($handle)Releases the stream resource.

The $mode controls access: 'r' (read), 'w' (write, truncate), 'a' (append), and the '+' variants for read and write.

For one-off reads and writes you usually don't need to manage a handle at all — the high-level helpers file_get_contents() and file_put_contents() open, transfer, and close a stream for you in a single call.

Stream wrappers and types

The wrapper at the start of the target string decides the type of stream:

  • File streams (file://, or just a bare path) — read and write data on the filesystem. See PHP File Handling and Open and Read a File.
  • Memory streams (php://memory, php://temp) — a read/write buffer that lives in RAM; great for building data in tests without touching disk.
  • I/O streams (php://stdin, php://stdout, php://input) — standard input/output and the raw request body.
  • Network / socket streams (tcp://, ssl://) — read and write over a network connection.
  • HTTP/FTP streams (http://, https://, ftp://) — fetch remote documents as if they were files (requires allow_url_fopen to be enabled).

Reading a file line by line

This minimal, self-contained example writes a small file, reads it back through a stream one line at a time, then cleans up:

<?php

$path = sys_get_temp_dir() . '/stream-demo.txt';

// Write three lines using the high-level helper.
file_put_contents($path, "alpha\nbeta\ngamma\n");

// Read them back through a stream handle.
$handle = fopen($path, 'r');
if ($handle === false) {
    exit("Could not open the stream.\n");
}

while (!feof($handle)) {
    $line = fgets($handle);
    if ($line !== false) {
        echo "Line: " . trim($line) . PHP_EOL;
    }
}

fclose($handle);
unlink($path);

Output:

Line: alpha
Line: beta
Line: gamma

We open the file in read mode, loop until feof() reports the end, and read each line with fgets(). Always check that fopen() did not return false before using the handle, and call fclose() when you are done.

Using a memory stream

Memory streams behave like files but never hit the disk — useful for assembling output or for unit tests:

<?php

$handle = fopen('php://memory', 'r+');

fwrite($handle, "buffered data");

// Rewind to the start before reading what we wrote.
rewind($handle);

echo fread($handle, 1024);

fclose($handle);

Output:

buffered data

After writing, you must rewind() the pointer back to the beginning before reading, because the internal position sits at the end of what you just wrote.

Reading a remote stream

Because HTTP is just another wrapper, the same loop works against a URL when allow_url_fopen is enabled:

<?php

$handle = fopen('https://www.example.com', 'r');
if ($handle === false) {
    exit("Failed to open the remote stream.\n");
}

while (!feof($handle)) {
    echo fgets($handle);
}

fclose($handle);

This example needs network access and the allow_url_fopen setting turned on, so it will not run in an offline sandbox. For real applications a dedicated HTTP client such as cURL gives you better control over headers, timeouts, and errors.

Error handling

Stream functions signal failure by returning false rather than throwing, so guard every call:

  • Check the return value of fopen() before reading or writing.
  • Wrap risky operations in try/catch if you convert warnings to exceptions — see PHP Exceptions.
  • Always fclose() handles you open to free resources.

Conclusion

Streams give PHP a single, consistent interface for every kind of data flow — files, memory buffers, sockets, and HTTP responses. Learn the small set of core functions (fopen, fread/fgets, fwrite, feof, fclose), understand wrappers like file:// and php://memory, and lean on the high-level helpers file_get_contents()/file_put_contents() for simple cases. To go further, explore creating and writing files and proper error handling.

Practice

Practice
What can PHP streams be used for?
What can PHP streams be used for?
Was this page helpful?