File System Functions
Beyond reading and writing content, PHP scripts frequently need to ask questions about the filesystem itself: does this file exist, is it a file or a directory, how big is it, can I even write to it? PHP provides a set of small, focused functions for exactly this — most of them named plainly enough to guess what they do. This page covers the most commonly used ones: file_exists, is_file/is_dir, filesize, unlink, copy, rename, and a brief look at chmod.
file_exists(): checking before you act
file_exists($path) returns true if something — a file or a directory — exists at the given path, and false otherwise. It's the first check to run before opening, deleting, or renaming anything, since most of the destructive functions below fail quietly or throw a warning rather than a catchable exception when the target is missing.
file-exists.php
<?php
$path = 'uploads/avatar.png';
if (file_exists($path)) {
echo 'File is present';
} else {
echo 'Nothing at that path';
}is_file() and is_dir(): telling files from directories
file_exists() doesn't tell you what kind of thing exists at a path — it could be a regular file or a directory. is_file($path) and is_dir($path) narrow that down. This distinction matters whenever code walks a mix of files and subdirectories, since trying to fopen() a directory as if it were a file fails in confusing ways.
is-file-is-dir.php
<?php
$targets = ['uploads', 'uploads/avatar.png', 'missing.txt'];
foreach ($targets as $target) {
if (is_dir($target)) {
echo "$target is a directory" . PHP_EOL;
} elseif (is_file($target)) {
echo "$target is a file" . PHP_EOL;
} else {
echo "$target does not exist" . PHP_EOL;
}
}uploads is a directory uploads/avatar.png is a file missing.txt does not exist
filesize(): checking size before loading
filesize($path) returns the size of a file in bytes. It's a cheap way to guard against accidentally loading an enormous file into memory with file_get_contents() — check the size first, and fall back to a line-by-line read if it's larger than you expect.
filesize-guard.php
<?php
$path = 'export.csv';
$maxBytes = 10 * 1024 * 1024; // 10 MB
if (filesize($path) > $maxBytes) {
echo 'File too large to load in one go, streaming instead.';
} else {
$contents = file_get_contents($path);
echo strlen($contents) . ' bytes loaded';
}unlink(): deleting files
unlink($path) deletes a file, returning true on success. There's no undo and no recycle bin — once unlink() succeeds, the file is gone. It only works on files, not directories (directories are removed with rmdir(), covered on the directories page).
unlink-example.php
<?php
$tempFile = 'cache/session_abc123.tmp';
if (file_exists($tempFile) && unlink($tempFile)) {
echo 'Temporary file removed';
}copy() and rename(): duplicating and moving files
copy($source, $destination) duplicates a file, leaving the original in place; rename($source, $destination) moves or renames a file (or a directory), removing it from the original location. Both return true on success and silently overwrite an existing file at the destination, so it's worth checking with file_exists() first if overwriting would be a mistake.
copy-rename.php
<?php
copy('report.pdf', 'archive/report-2024-01.pdf');
if (!file_exists('archive/report-2024-02.pdf')) {
rename('report.pdf', 'archive/report-2024-02.pdf');
} else {
echo 'Destination already exists, skipping rename';
}chmod(): basic permission changes
chmod($path, $mode) changes a file's permissions, using the same octal notation as the Unix chmod command — for example 0644 for "owner can read and write, everyone else can only read." It's most often needed after creating a file that a web server process needs to read but that shouldn't be world-writable. On Windows, chmod() has very limited effect, since the underlying permission model is different.
chmod-example.php
<?php
file_put_contents('uploads/report.pdf', $pdfContents);
chmod('uploads/report.pdf', 0644);Function | Purpose |
|---|---|
file_exists() | Check whether a path (file or directory) exists |
is_file() | Check whether a path is a regular file |
is_dir() | Check whether a path is a directory |
filesize() | Get a file's size in bytes |
is_readable() / is_writable() | Check read/write permission before operating |
unlink() | Delete a file permanently |
copy() | Duplicate a file to a new location |
rename() | Move or rename a file or directory |
chmod() | Change a file's permission bits (limited effect on Windows) |
file_exists()tells you something is there, not what kind of thing it is — pair it withis_file()/is_dir().unlink()and overwritingcopy()/rename()calls are irreversible; validate paths carefully.Checking
is_writable()/is_readable()up front produces clearer errors than reacting to a failed operation.Never build a path passed to any of these functions directly from unvalidated user input.