Problems and solutions caused by PHP file lock (a real case)
A real case
I remembered that I had made a related mistake before. The scene at that time was this: There was a WeChat public account project, and the interface to call the WeChat public account required access_token
, and its validity period is 2 hours. What I did at that time was to store it in a file, and the format was json
. {"access_token":"easWasdw32323", "expire":1588219064}
. The pseudo code is as follows:
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 = ...; // 调用微信接口获取到token fwrite($fp, json_encode($tokenJson)); return $tokenJson['access_token']; }
Problems that occur:
There will be problems after the project runs for a period of time, but it will be normal after refreshing after a second or two.
Analysis of the cause of the problem:
Assume that the token has expired. At this time, two requests come, named A and B respectively. When A comes, he finds that after the token expires, he calls the WeChat interface to obtain a new token. After obtaining it, he updates it to the file storing the token.
However, when the file was not completely updated, B came and read in the file storing the token. Because the data in the token file is not updated completely, the data read by B will cause errors.
In addition, it is possible that A and B are updating the file content at the same time, which will cause data confusion and lead to errors.
How to avoid this error?
The file locking mechanism can be completed.
The flock() function is provided in PHP, which can use the locking mechanism (lock or release the file) on the file. When a process locks a file when accessing it, other processes must wait until the lock is released if they want to access the file. This avoids data corruption during concurrent access to the same file.
The function prototype is as follows:
flock ( resource $handle , int $operation [, int &$wouldblock ] ) : bool
-
handle
:The file system pointer is a resource typically created by fopen().
## Operation
- wouldblock
If the lock will block (EWOULDBLOCK error code), the optional third The parameter will be set to TRUE. (Not supported on Windows)
<?php
$file = 'data.txt';
$handler = fopen($file, 'a+') or die('文件资源打开失败');
// 取得独占锁
if (flock($handler, LOCK_EX)) {
sleep(5);
flock($handler, LOCK_UN);
} else {
echo '锁定失败';
}
fclose($handler);
Copy after login
demo2.php<?php $file = 'data.txt'; $handler = fopen($file, 'a+') or die('文件资源打开失败'); // 取得独占锁 if (flock($handler, LOCK_EX)) { sleep(5); flock($handler, LOCK_UN); } else { echo '锁定失败'; } fclose($handler);
<?php $file = 'data.txt'; $handler = fopen($file, 'a+') or die('文件资源打开失败'); // 取得独占锁 if (flock($handler, LOCK_EX)) { fwrite($handler, 'sometest string'); flock($handler, LOCK_UN); } else { echo '锁定失败'; } fclose($handler);
<?php
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'); // 取得独占锁
if (flock($fp, LOCK_EX)) {
$tokenJson = ...; // 调用微信接口获取到token
fwrite($fp, json_encode($tokenJson));
flock($fp, LOCK_UN);
} else {
return false;
}
return $tokenJson['access_token'];
}
Copy after login
<?php 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'); // 取得独占锁 if (flock($fp, LOCK_EX)) { $tokenJson = ...; // 调用微信接口获取到token fwrite($fp, json_encode($tokenJson)); flock($fp, LOCK_UN); } else { return false; } return $tokenJson['access_token']; }
The above is the detailed content of Problems and solutions caused by PHP file lock (a real case). For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Alipay PHP...

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

Session hijacking can be achieved through the following steps: 1. Obtain the session ID, 2. Use the session ID, 3. Keep the session active. The methods to prevent session hijacking in PHP include: 1. Use the session_regenerate_id() function to regenerate the session ID, 2. Store session data through the database, 3. Ensure that all session data is transmitted through HTTPS.

The enumeration function in PHP8.1 enhances the clarity and type safety of the code by defining named constants. 1) Enumerations can be integers, strings or objects, improving code readability and type safety. 2) Enumeration is based on class and supports object-oriented features such as traversal and reflection. 3) Enumeration can be used for comparison and assignment to ensure type safety. 4) Enumeration supports adding methods to implement complex logic. 5) Strict type checking and error handling can avoid common errors. 6) Enumeration reduces magic value and improves maintainability, but pay attention to performance optimization.

The application of SOLID principle in PHP development includes: 1. Single responsibility principle (SRP): Each class is responsible for only one function. 2. Open and close principle (OCP): Changes are achieved through extension rather than modification. 3. Lisch's Substitution Principle (LSP): Subclasses can replace base classes without affecting program accuracy. 4. Interface isolation principle (ISP): Use fine-grained interfaces to avoid dependencies and unused methods. 5. Dependency inversion principle (DIP): High and low-level modules rely on abstraction and are implemented through dependency injection.

How to debug CLI mode in PHPStorm? When developing with PHPStorm, sometimes we need to debug PHP in command line interface (CLI) mode...

Sending JSON data using PHP's cURL library In PHP development, it is often necessary to interact with external APIs. One of the common ways is to use cURL library to send POST�...

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.
