PHP Filesystem
In this article, we will be discussing the PHP Filesystem functions that are available in PHP. These functions allow you to perform various operations on files
Introduction
The PHP filesystem functions let your scripts read from and write to the server's disk: creating, reading, updating, and deleting files, and managing directories. They are the foundation of anything that has to persist data outside of a database — log files, generated reports, uploaded user files, configuration, caches, and import/export jobs.
This article explains the two main ways to work with files (the handle-based family built around fopen(), and the one-shot helpers like file_get_contents()), shows runnable examples for each, and points out the permission and error-handling gotchas that trip people up in production.
Two ways to work with files
PHP gives you two styles, and choosing the right one keeps your code simple:
- One-shot helpers —
file_get_contents()andfile_put_contents()read or write an entire file in a single call. Use these when the file fits comfortably in memory (config files, small JSON/CSV, templates). They are the shortest, most readable option. - Handle-based functions —
fopen(),fread(),fwrite(), andfclose()give you a file handle (a resource) that you read or write incrementally. Use these for large files you want to stream line-by-line without loading everything into memory, or when you need to keep a file open across many operations.
File Operations
PHP provides several functions for working with files. These functions allow you to create, open, read, write, and delete files. The most commonly used file functions include:
fopen(): Opens a file and returns a handle. It takes two arguments: the file name and the mode in which to open it (see the table below).fclose(): Closes an open file handle and flushes any buffered writes to disk.fwrite(): Writes a string to an open file, returning the number of bytes written.fread(): Reads a given number of bytes from an open file.feof(): Returnstrueonce the end of the file has been reached — useful as a loop condition when reading.unlink(): Deletes a file.filesize(): Returns the size of a file in bytes.file_exists(): Checks whether a file or directory exists before you act on it.
For simple read/write tasks, prefer file_get_contents() and file_put_contents(), which handle opening, reading/writing, and closing in a single call.
File modes for fopen()
The second argument to fopen() controls what you can do with the handle and what happens to existing content. The most common modes are:
| Mode | Meaning |
|---|---|
"r" | Read only. Pointer starts at the beginning. Fails if the file does not exist. |
"w" | Write only. Truncates the file to zero length (or creates it). |
"a" | Write only, append. Creates the file if missing; existing content is preserved. |
"x" | Write only, but fails if the file already exists — safe "create new" mode. |
"r+" | Read and write. Pointer at the beginning; file must exist. |
Gotcha:
"w"deletes existing content the moment you open the file. If you want to add to a log instead of overwriting it, use"a".
Directory Operations
PHP also provides functions for working with directories. These functions allow you to create, delete, and manipulate directories. Some of the most commonly used directory functions include:
mkdir(): This function is used to create a directory.rmdir(): This function is used to delete a directory.opendir(): This function is used to open a directory.readdir(): This function is used to read the contents of a directory.closedir(): This function is used to close an open directory.
Examples
Let's look at how these functions are used in practice.
Creating and writing a file
To create a file and write to it, open it in write mode with fopen(), write with fwrite(), then always fclose():
<?php
$file = fopen("example.txt", "w");
if ($file === false) {
exit("Error opening file");
}
fwrite($file, "Hello, world!");
fclose($file);This creates example.txt in the same directory as the script (replacing it if it already exists), writes Hello, world!, and closes the handle.
The same task with the one-shot helper is a single line — this is the preferred style for small files:
<?php
file_put_contents("example.txt", "Hello, world!");Reading a file
To read a file with a handle, open it in read mode and use fread(). Passing filesize() tells fread() how many bytes to read:
<?php
$file = fopen("example.txt", "r");
if ($file === false) {
exit("Error opening file");
}
echo fread($file, filesize("example.txt"));
fclose($file);For small files, file_get_contents() does the same thing in one call:
<?php
echo file_get_contents("example.txt");Reading a file line by line
For large files, read line by line with fgets() so you never hold the whole file in memory. The loop runs until feof() reports end-of-file:
<?php
$file = fopen("example.txt", "r");
if ($file === false) {
exit("Error opening file");
}
while (!feof($file)) {
$line = fgets($file);
echo $line;
}
fclose($file);Appending to a file
To add to a file without erasing what's already there, open it in append mode ("a"). This is the right mode for logs:
<?php
$file = fopen("log.txt", "a");
fwrite($file, "New log entry\n");
fclose($file);Creating a Directory
To create a directory, use the mkdir() function:
<?php
mkdir("example_directory");This creates a directory called example_directory next to the script. To create nested directories in one call, pass the mode and the recursive flag:
<?php
mkdir("parent/child/grandchild", 0755, true);Note:
mkdir()requires write permission on the parent directory. The third argument (true) enables recursive creation of intermediate directories.
Deleting a File
To delete a file, use the unlink() function:
<?php
if (file_exists("example.txt")) {
unlink("example.txt");
}Checking with file_exists() first avoids a warning when the file is already gone.
Best practices
- Always close handles. Every
fopen()should be paired withfclose()so buffered writes are flushed and the resource is released. - Check return values.
fopen(),mkdir(), andunlink()returnfalseon failure — guard against it instead of assuming success. - Mind permissions. Most "permission denied" errors come from the web-server user not owning the target directory, not from your code.
- Choose the right tool. Reach for
file_get_contents()/file_put_contents()for whole-file work; use thefopen()/fread()family only when you need streaming.
Conclusion
The filesystem functions provide the foundation for file and directory management in PHP. By understanding the difference between one-shot helpers and handle-based streaming, choosing the correct fopen() mode, and cleaning up handles safely, you can build robust applications that store data and configuration reliably. To go deeper, explore PHP File Handling, PHP File Open/Read, and working with directories.