W3docs

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
ParameterDescription
$streamA file pointer returned by fopen().
$operationOne of the lock constants below, optionally OR'd with LOCK_NB.
$would_blockOptional. 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

ConstantMeaning
LOCK_SHShared lock (reader). Many processes may hold a shared lock at once, but none may hold an exclusive one meanwhile. Use it when reading.
LOCK_EXExclusive lock (writer). Only one process can hold it; everyone else — readers and writers — waits. Use it when writing.
LOCK_UNRelease the lock currently held on the stream.
LOCK_NBNon-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:

  1. Open the file with fopen() using a mode that fits what you'll do ('r+', 'c', 'a', …).
  2. Acquire the lock with flock($file, LOCK_EX) (or LOCK_SH to read).
  3. Read or write the file.
  4. Release with flock($file, LOCK_UN) and close with fclose().

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 with ftruncate() 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 with LOCK_UN so 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().

Practice

Practice
What is the function of flock() in PHP?
What is the function of flock() in PHP?
Was this page helpful?