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://, orphp://memorythat 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:
| Function | What 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 (requiresallow_url_fopento 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: gammaWe 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 dataAfter 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_fopensetting 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/catchif 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.