flock()
The flock() function is a built-in PHP function that allows you to perform a simple file locking mechanism. This function is used to prevent multiple processes
What is the flock() Function?
The flock() function performs file locking in PHP. A lock lets one process tell others, "I'm working with this file — wait your turn." Without it, two scripts running at the same time can interleave their writes and corrupt a file. This is a classic race condition, and flock() is the simplest tool PHP gives you to prevent it.
This page covers what the function does, its lock types, a complete working example you can run, the gotchas that trip people up, and where it fits among PHP's other file functions.
A word on "advisory" locking
On Unix-like systems flock() is advisory: the lock is only honored by processes that also call flock() on the same file. A program that ignores locking can still read or overwrite the file freely. So locking only protects you if every script that touches the file cooperates. On Windows, locking is mandatory (enforced by the OS), so behavior differs slightly across platforms — don't rely on mandatory enforcement in portable code.
Syntax
flock($stream, $operation, &$would_block = null): bool| Parameter | Description |
|---|---|
$stream | A file pointer returned by fopen(). |
$operation | One of the lock constants below, optionally OR'd with LOCK_NB. |
$would_block | Optional. Set to 1 if the lock would have blocked (only meaningful with LOCK_NB). Passed by reference. |
The function returns true on success or false on failure.
Lock types
| Constant | Meaning |
|---|---|
LOCK_SH | Shared lock (reader). Many processes may hold a shared lock at once, but none may hold an exclusive one meanwhile. Use it when reading. |
LOCK_EX | Exclusive lock (writer). Only one process can hold it; everyone else — readers and writers — waits. Use it when writing. |
LOCK_UN | Release the lock currently held on the stream. |
LOCK_NB | Non-blocking modifier. OR it with LOCK_SH or LOCK_EX (e.g. `LOCK_EX |
By default flock() blocks: if another process holds an exclusive lock, your call sits and waits until the lock is free. Add LOCK_NB when you'd rather fail fast.
How to Use the flock() Function
The pattern is always the same four steps:
- Open the file with
fopen()using a mode that fits what you'll do ('r+','c','a', …). - Acquire the lock with
flock($file, LOCK_EX)(orLOCK_SHto read). - Read or write the file.
- Release with
flock($file, LOCK_UN)and close withfclose().
A complete, runnable example
This script opens a counter file, locks it exclusively, increments the stored number, and writes it back — the kind of read-modify-write that must be locked to be safe under concurrency:
<?php
$filename = 'counter.txt';
// 'c' opens for read/write, creating the file if missing,
// and does NOT truncate it (unlike 'w').
$file = fopen($filename, 'c+');
if ($file === false) {
exit("Could not open file.\n");
}
if (flock($file, LOCK_EX)) { // block until we hold the lock
$current = (int) stream_get_contents($file);
$current++;
rewind($file); // back to the start
ftruncate($file, 0); // clear old contents
fwrite($file, (string) $current);
fflush($file); // push to disk before unlocking
flock($file, LOCK_UN); // release the lock
echo "Counter is now: $current\n";
} else {
echo "Could not acquire lock.\n";
}
fclose($file);Running it three times prints Counter is now: 1, then 2, then 3. Because the read-increment-write happens under LOCK_EX, two processes can never read the same value and both write 2.
Failing fast with a non-blocking lock
When you don't want to wait — say a cron job that should skip the run if a previous one is still going — combine LOCK_EX with LOCK_NB:
<?php
$file = fopen('job.lock', 'c');
if (flock($file, LOCK_EX | LOCK_NB)) {
echo "Got the lock, doing work...\n";
// ... long-running task ...
flock($file, LOCK_UN);
} else {
echo "Another instance is already running. Exiting.\n";
}
fclose($file);Common gotchas
- Locks attach to the open file handle, not the path. Calling
fopen()twice on the same file gives you two independent handles, and a lock on one does not block the other in the same process. - Use
'c'/'c+', not'w', when locking. Mode'w'truncates the file the instant you open it — before you acquire the lock — defeating the purpose. Truncate explicitly withftruncate()after you hold the lock. flock()does not work reliably over NFS or some networked/FAT filesystems. For multi-server coordination, use a real lock service (a database row lock, Redis, etc.) instead.fclose()releases any remaining lock, but unlock explicitly withLOCK_UNso the file is available again as soon as you're done.
Conclusion
flock() is PHP's built-in tool for coordinating concurrent access to a file. Use LOCK_EX around writes, LOCK_SH around reads, and LOCK_NB when you'd rather fail than wait. Remember that locking on Unix is advisory — it only protects you when every script that touches the file participates. For higher-level file work, see fwrite(), fread(), and file_put_contents().