PHP File Handling
PHP provides various ways to manipulate files and folders on the server. In this article, we will discuss the file handling capabilities of PHP, specifically
File handling is one of the most common tasks in server-side programming: writing logs, generating reports, caching data, importing CSV files, and serving downloads all depend on it. PHP ships with a rich set of built-in functions for working with files, so you rarely need an external library.
This chapter covers the full lifecycle of a file — create, read, update, and delete (CRUD) — and explains when to reach for each approach. Broadly, PHP gives you two styles:
- Whole-file helpers (
file_get_contents(),file_put_contents()) — one line, perfect for small files you can hold in memory. - Stream-based functions (
fopen(),fread(),fwrite(),fgets(),fclose()) — give you a handle so you can read or write a large file piece by piece without loading it all at once.
Knowing which to use is the difference between code that works on a 2 KB config file and code that survives a 2 GB log file.
File Modes
Every stream-based call starts with fopen($filename, $mode), and the mode is the part beginners get wrong most often. It decides whether the file is opened for reading, writing, or both, whether existing content is erased, and where the internal pointer starts.
| Mode | Read | Write | Pointer | If file is missing | Existing content |
|---|---|---|---|---|---|
"r" | yes | no | start | warning, returns false | kept |
"r+" | yes | yes | start | warning, returns false | kept |
"w" | no | yes | start | created | erased (truncated) |
"w+" | yes | yes | start | created | erased (truncated) |
"a" | no | yes | end | created | kept (appends) |
"a+" | yes | yes | end | created | kept (appends) |
"x" | no | yes | start | created | fails if file already exists |
Add "b" (e.g. "rb", "wb") for binary-safe access when working with images, PDFs, or any non-text data — it prevents line-ending translation on Windows.
Creating and Writing a File
To create a file you open it in a write mode with fopen() and write to it with fwrite(). Always close the handle with fclose() when you are done — this flushes the buffer to disk and frees the resource.
<?php
$file = fopen("test.txt", "w"); // create/truncate, open for writing
fwrite($file, "Hello World\n");
fwrite($file, "Second line\n"); // each call appends after the previous one
fclose($file); // flush to disk and release the handleOpening with "w" erases any existing content. To add to a file without destroying what is already there, open it in append mode ("a") instead:
<?php
$log = fopen("app.log", "a"); // pointer starts at end of file
fwrite($log, "User logged in at " . date("H:i:s") . "\n");
fclose($log);For a quick one-liner when you have the whole string in memory, skip the handle entirely and use file_put_contents():
<?php
file_put_contents("test.txt", "Hello World\n"); // overwrite
file_put_contents("app.log", "another line\n", FILE_APPEND); // appendAlways check the return value of
fopen(). If the path is wrong or the directory is not writable it returnsfalseand PHP emits a warning — usingfalseas a handle will then fail silently.
<?php
$file = fopen("/protected/test.txt", "w");
if ($file === false) {
die("Could not open the file for writing.");
}
fwrite($file, "data");
fclose($file);Reading a File
The simplest way to read a small file is file_get_contents(), which returns the entire contents as a single string:
<?php
$content = file_get_contents("test.txt");
echo $content; // prints everything in the fileWhen the file is large, reading it all into memory is wasteful. Read it line by line with fgets(), looping until feof() (end-of-file) is reached:
<?php
$file = fopen("test.txt", "r");
while (!feof($file)) {
$line = fgets($file); // reads one line, including the newline
echo $line;
}
fclose($file);If you want every line as an array element in one call, file() is handy — but, like file_get_contents(), it loads the whole file into memory:
<?php
$lines = file("test.txt"); // array, one element per line
echo "This file has " . count($lines) . " lines.";A good habit is to confirm a file exists before reading it, using file_exists() (or is_readable() to also check permissions):
<?php
if (file_exists("test.txt")) {
echo file_get_contents("test.txt");
} else {
echo "File not found.";
}Updating a File
To replace the contents of a file, the cleanest tool is file_put_contents(). It opens, writes, and closes in a single call:
<?php
$content = "Hello World Again\n";
file_put_contents("test.txt", $content); // replaces the old contentsTo add to a file rather than replace it, pass the FILE_APPEND flag (shown above) or open it in append mode with fopen(). There is no single "edit line 3" function — to change part of a file you typically read it, modify the data in PHP, and write it back.
Deleting a File
Use unlink() — note the unusual name — to remove a file. It returns true on success and false on failure, so guard it with file_exists() to avoid a warning:
<?php
if (file_exists("test.txt")) {
if (unlink("test.txt")) {
echo "File deleted.";
} else {
echo "Could not delete the file.";
}
} else {
echo "Nothing to delete.";
}unlink() only removes files. To delete an empty directory use rmdir(); see PHP Directory for working with folders.
When to Use Which Approach
- Small text/config files, whole content at once →
file_get_contents()/file_put_contents(). - Large files, line-by-line streaming →
fopen()+fgets()/fread(). - Appending to a log → mode
"a", orFILE_APPEND. - Creating a file only if it does not exist yet → mode
"x". - Binary data (images, PDFs) → add the
"b"flag and usefread()/fwrite().
Summary
File handling is a core part of server-side PHP. You learned the two families of functions — the one-line whole-file helpers and the stream-based handle functions — and when each is appropriate, how file modes control truncation and appending, how to read large files efficiently with fgets()/feof(), and how to update and safely delete files.
To go deeper, explore the dedicated chapters: Create and Write a File, Open and Read a File, PHP Filesystem functions, File Upload, and PHP Directory.