chmod()
chmod() is a PHP function used to change the file mode. The file mode determines who can access the file and what permissions they have. It's a crucial function
Understanding PHP chmod() Function
chmod() changes the mode (the permission bits) of a file or directory on a Unix-like filesystem. The mode controls who can do what with the file: read its contents, write to it, or execute it. Getting permissions right matters for security — too permissive and anyone can read or overwrite sensitive data; too strict and your web server can't read the files it needs to serve.
This page covers the syntax, how to read and write the octal mode, the most common permission values you'll actually use, the return value, and the gotchas that trip people up (the leading zero, umask, and Windows).
Syntax
chmod(string $filename, int $permissions): bool| Parameter | Description |
|---|---|
$filename | Path to the file or directory whose permissions you want to change. |
$permissions | The new mode, as an octal integer (for example 0644). |
It returns true on success and false on failure.
How the octal mode works
The mode is a three-digit octal number. Each digit describes one class of user:
| Digit position | Applies to |
|---|---|
| 1st (e.g. 644) | Owner of the file |
| 2nd (e.g. 644) | Group |
| 3rd (e.g. 644) | Others (everyone else) |
Each digit is the sum of the permissions you grant to that class:
| Value | Permission |
|---|---|
4 | Read |
2 | Write |
1 | Execute |
0 | None |
Add them up: read + write = 4 + 2 = 6, and read + execute = 4 + 1 = 5. So 0750 means owner: read/write/execute (7), group: read/execute (5), others: nothing (0).
In PHP, the mode must be written with a leading 0 so it is interpreted as octal. chmod("file.txt", 644) passes the decimal number 644, which is the octal value 1204 — almost certainly not what you want. Always write 0644.
Common permission values
| Mode | Owner | Group | Others | Typical use |
|---|---|---|---|---|
0644 | read/write | read | read | Regular files (HTML, images, config the server reads) |
0600 | read/write | – | – | Private files (credentials, keys) |
0755 | read/write/execute | read/execute | read/execute | Directories and executable scripts |
0700 | read/write/execute | – | – | Private directories |
0777 | all | all | all | Rarely a good idea — anyone can read and overwrite |
Examples
Set permissions on a single file
The mode 0644 lets the owner read and write, while the group and everyone else can only read:
<?php
if (chmod("example.txt", 0644)) {
echo "Permissions updated.";
} else {
echo "Failed to change permissions.";
}Make a script executable
To run a PHP script directly (e.g. a CLI cron job), the owner needs execute permission:
<?php
chmod("backup.php", 0744); // owner: rwx, group & others: read onlyAlways check the return value
chmod() fails silently by returning false — for example when the script doesn't own the file. Don't assume it worked:
<?php
$file = "config.ini";
if (!chmod($file, 0600)) {
error_log("Could not secure {$file}");
}Gotchas
- Ownership matters. A process can only
chmod()a file it owns (or as the superuser). On shared hosting the web server user often isn't the owner, so the call returnsfalse. umaskdoes not affectchmod(). Unlikemkdir()and file creation,chmod()sets the mode you ask for verbatim. Theumaskonly masks newly created files — see umask().- Windows ignores most bits. NTFS has no Unix permission model, so on Windows only the read-only bit is meaningfully affected.
- Check before you change. Use is_writable() to test access, and fileperms() to read the current mode before overwriting it.
Related functions
- fileperms() — read a file's current permission bits.
- is_writable() — test whether the script can write to a path.
- umask() — set the default mask applied to newly created files.
- mkdir() — create a directory with a given mode.
Conclusion
chmod() is your tool for tightening or loosening access to files and directories from PHP. Remember the three rules that prevent most bugs: write the mode in octal with a leading zero, pick the least permission that still works (0644 for files, 0755 for directories), and check the return value because the function fails quietly when your script doesn't own the target.