PHPFile System Functions

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
<?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
<?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
<?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
<?php

$tempFile = 'cache/session_abc123.tmp';

if (file_exists($tempFile) && unlink($tempFile)) {
    echo 'Temporary file removed';
}
unlink() is permanent and immediate
There's no confirmation step and no trash folder — calling `unlink()` on the wrong path deletes real data instantly. Always confirm the path is exactly what you expect (ideally built from a known-safe base directory plus a validated filename, never raw user input) before calling it.
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
<?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
<?php

file_put_contents('uploads/report.pdf', $pdfContents);
chmod('uploads/report.pdf', 0644);
Check permissions before operating, don't just guess
Rather than attempting a write and only discovering a permissions problem from a warning, check `is_writable($path)` (or `is_readable($path)` for reads) first when the outcome matters — for example before starting a long-running export. It lets you fail with a clear, specific message instead of a generic I/O warning partway through the operation.

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 with is_file()/is_dir().

  • unlink() and overwriting copy()/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.

Tip
When working with paths that partly come from configuration or user choices — an upload directory, a selected export format — resolve the final path with `realpath()` and confirm it still starts with your intended base directory before calling `unlink()`, `copy()`, or `rename()` on it. That one check closes off path traversal attempts that a simple string check might miss.