Backend Development 6 min read

Preventing Concurrent Access Issues with WeChat Access Tokens Using PHP File Lock (flock)

This article explains a real-world case where storing WeChat access tokens in a JSON file caused race conditions, analyzes the root cause, and demonstrates how to use PHP's flock() function with proper locking to safely read and write the token, including sample code.

php中文网 Courses
php中文网 Courses
php中文网 Courses
Preventing Concurrent Access Issues with WeChat Access Tokens Using PHP File Lock (flock)

A WeChat public account project stores the access_token (valid for 2 hours) in a JSON file. When the token expires, concurrent requests may read or write the file simultaneously, leading to errors.

Example of the stored JSON:

<code>{"access_token":"easWasdw32323", "expire":1588219064}</code>

Pseudocode used originally:

<code>function getToken($tokenFile) {
    $tokenJson = file_get_contents($tokenFile);
    if (!$tokenJson) {
        $token = loadToken($tokenFile);
    } else if (json_decode($tokenJson, true)['expire'] <= time()) {
        $token = loadToken($tokenFile);
    } else {
        $token = json_decode($tokenJson, true)['access_token'];
    }
    return $token;
}

function loadToken($tokenFile) {
    $fp = fopen($tokenFile, 'r+');
    $tokenJson = ...; // call WeChat API to get token
    fwrite($fp, json_encode($tokenJson));
    return $tokenJson['access_token'];
}</code>

Problem: after the token expires, two simultaneous requests (A and B) may both try to refresh it. Request A updates the file, but before the write completes, request B reads the partially‑written file and obtains an invalid token, causing intermittent failures.

Solution: use a file‑locking mechanism. PHP provides flock() to acquire shared (LOCK_SH) or exclusive (LOCK_EX) locks on a file handle, ensuring that only one process writes at a time.

Function prototype:

<code>flock(resource $handle, int $operation [, int &$wouldblock]) : bool</code>

Lock constants:

LOCK_SH – shared lock for reading

LOCK_EX – exclusive lock for writing

LOCK_UN – release lock

LOCK_NB – non‑blocking lock (not supported on Windows)

Demo 1 (demo1.php) acquires an exclusive lock, sleeps for 5 seconds, then releases the lock:

<code>&lt;?php
$file = 'data.txt';
$handler = fopen($file, 'a+') or die('Failed to open file');
if (flock($handler, LOCK_EX)) {
    sleep(5);
    flock($handler, LOCK_UN);
} else {
    echo 'Lock failed';
}
fclose($handler);
</code>

Demo 2 (demo2.php) tries to acquire the same exclusive lock and write a string:

<code>&lt;?php
$file = 'data.txt';
$handler = fopen($file, 'a+') or die('Failed to open file');
if (flock($handler, LOCK_EX)) {
    fwrite($handler, 'sometest string');
    flock($handler, LOCK_UN);
} else {
    echo 'Lock failed';
}
fclose($handler);
</code>

Running demo1.php followed immediately by demo2.php shows that demo2.php cannot write until demo1.php releases the lock, proving the effectiveness of the locking strategy.

After learning the locking technique, the token‑handling code is revised to acquire an exclusive lock before reading or writing the token file, ensuring that concurrent requests no longer corrupt the token data.

<code>function getToken($tokenFile) {
    $tokenJson = file_get_contents($tokenFile);
    if (!$tokenJson) {
        $token = loadToken($tokenFile);
    } else if (json_decode($tokenJson, true)['expire'] <= time()) {
        $token = loadToken($tokenFile);
    } else {
        $token = json_decode($tokenJson, true)['access_token'];
    }
    return $token;
}

function loadToken($tokenFile) {
    $fp = fopen($tokenFile, 'w'); // obtain exclusive lock
    if (flock($fp, LOCK_EX)) {
        $tokenJson = ...; // call WeChat API
        fwrite($fp, json_encode($tokenJson));
        flock($fp, LOCK_UN);
    } else {
        return false;
    }
    return $tokenJson['access_token'];
}
</code>
concurrencyWeChataccess tokenfile-lock
php中文网 Courses
Written by

php中文网 Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.