is_writable()
PHP is_writable() returns true if a file or directory is writable by the current process. Learn its syntax, gotchas, and the stat-cache caveat.
The PHP is_writable() function tells you, before you try to write, whether the current process is allowed to write to a given file or directory. This page covers its syntax, return value, the caching behavior that trips people up, and the practical patterns for using it safely.
What is the is_writable() Function?
is_writable() is a built-in PHP function that returns true if the named file (or directory) exists and is writable by the user the PHP process runs as, and false otherwise. The function takes one argument and performs no write itself — it only reports permission.
The check is based on the effective user ID of the running process (for example, www-data under Apache/Nginx-FPM), not the user who owns the script. A file you can edit in your editor may still be reported as non-writable to the web server.
is_writable() has an alias, is_writeable() (note the extra e); the two are identical.
Syntax
is_writable(string $filename): bool| Parameter | Description |
|---|---|
$filename | Path to the file or directory to check. Can be relative to the current working directory. |
Returns true on success, false if the path is not writable or does not exist.
How to Use the is_writable() Function
The typical pattern is "look before you leap" — confirm a file is writable before attempting to open it for writing, so you can fail with a clear message instead of a runtime warning.
Because the runner sandbox creates data.txt, the example above prints The file 'data.txt' is writable.
A complete, runnable example
This self-contained script creates a file, checks it, then only writes when the check passes:
<?php
$file = 'log.txt';
// Create the file so the example is reproducible.
file_put_contents($file, "first line\n");
if (is_writable($file)) {
file_put_contents($file, "second line\n", FILE_APPEND);
echo "Wrote to $file:\n";
echo file_get_contents($file);
} else {
echo "Cannot write to $file.";
}Output:
Wrote to log.txt:
first line
second lineChecking a directory
is_writable() works on directories too. This is the right check before you create a new file: you cannot test the file (it does not exist yet), so you test the folder that will contain it.
<?php
$dir = __DIR__; // the directory this script lives in
if (is_writable($dir)) {
echo "New files can be created in: $dir";
} else {
echo "Directory is read-only: $dir";
}Common Gotchas
- It does not throw — it warns. If
$filenameis invalid in a way PHP cannot resolve (e.g. an open_basedir violation), PHP may emit anE_WARNING. The return value is stillfalse. Suppress with@only as a last resort. - Results may be cached. PHP keeps a stat cache. If a file's permissions change during the same script run,
is_writable()can return a stale result. Callclearstatcache()before re-checking to force PHP to read the filesystem again. falseis ambiguous. Afalseresult means "not writable or does not exist." If you need to distinguish the two, combine it withfile_exists().- TOCTOU race condition. Between the
is_writable()check and the actual write, the file's permissions could change. For critical code, don't rely on the check alone — handle the failure of the write itself as well.
When you do change permissions mid-script and re-check, clear the cache first:
<?php
$file = 'config.ini';
file_put_contents($file, "data\n");
var_dump(is_writable($file)); // bool(true)
chmod($file, 0444); // make it read-only
clearstatcache(); // force PHP to re-read the filesystem
var_dump(is_writable($file)); // bool(false)Output:
bool(true)
bool(false)Related Functions
is_readable()— the read-permission counterpart.file_exists()— check existence without checking permissions.is_file()— confirm a path is a regular file.fopen()/fwrite()— open and write to files once the check passes.chmod()— change a file's permission bits.
Conclusion
is_writable() lets your script confirm write access up front and fail gracefully instead of triggering runtime warnings. Remember its three quirks: it reflects the process user's permissions, false also means "missing," and its results are cached until you call clearstatcache(). Pair it with the actual write's error handling for robust file code.