Reading the file content with empty file_put_contents() when using file_put_contents() in PHP 7.4
1. Check the put() method in illuminate\FileSystem\FileSystem to implement
public function put($path, $contents, $lock = false)
{
return file_put_contents($path, $contents, $lock ? LOCK_EX : 0);
}
2. Reference: that is, in the concurrency scenario, if you do not wrap it as follows, file_get_contents may return emptyhttps://www.php.net/manual/zh/function.file-put-contents.php#112831. It’s important to understand that lock_ex doesn’t prevent reading files unless you also use phpflockFunctions explicitly get read locks (shared locks). i.e. in concurrency scenarios, if you don’t wrap it like this, file_get_contents may return empty. If you have the code to do file_get_contents, change the string and then use file_put_contents to resave it again, you’d better make sure you do this correctly, otherwise your file will randomly wipe itself.
<?php
$myfile=fopen('test.txt','rt');
flock($myfile,LOCK_SH);
$read=file_get_contents('test.txt');
fclose($myfile);
?>
3. Decide to simulate the use of file_put_contents() to write the same path file in the test environment at the same time, and then observe whether the read file content is empty.
require.php
<?php
$i = rand();
$path = 'return.php';
$contents = [
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j'
];
if (file_exists($path)) {
$read = file_get_contents($path);
if (empty($read)) {
file_put_contents('empty-' . rand() . '.php', $read, LOCK_EX);
}
}
$code = '<?php';
$code .= "\n\n";
$contents = array_merge($contents, [$i]);
$code .= 'return ' . var_export($contents, true) . ';';
file_put_contents($path, $code, LOCK_EX);
?>
4. Reference:Use Alibaba Cloud Performance Testing PTS to simulate concurrent HTTP requests . Check the results of the program running, and it is determined that more than 20,000 files are generated, namely: return.php, and a large number of files starting with empty-. as shown in Figure 1
5. This concludes that if you have code to save the contents of the file using file_put_contents, although it has been added LOCK_EX, but in high concurrency scenarios, when reading the file content, there is a high probability that the file content is empty.
6. Decide to use PHP before reading the content of the fileflockFunctions explicitly get read locks (shared locks). The final code is implemented as follows
require.php
<?php
$i = rand();
$path = 'return.php';
$contents = [
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j'
];
if (file_exists($path)) {
$myfile = fopen($path, 'r');
flock($myfile, LOCK_SH);
$read = file_get_contents($path);
fclose($myfile);
if (empty($read)) {
file_put_contents('empty-' . rand() . '.php', $read, LOCK_EX);
}
}
$code = '<?php';
$code .= "\n\n";
$contents = array_merge($contents, [$i]);
$code .= 'return ' . var_export($contents, true) . ';';
file_put_contents($path, $code, LOCK_EX);
?>
7. Reference:Use Alibaba Cloud Performance Testing PTS to simulate concurrent HTTP requests . After re-concurrent tests, check the program running results again. The file that starts with empty – no longer exists, explain using phpflockFunctions explicitly fetching read locks (shared locks) are valid. However, during the program running, the content of the file return.php is still empty, but at this time, there is no direct reading of the content of the file, but waiting. such as video 1
8. However, after checking the test report, after adding the read lock, the performance has declined. The performance before and after the lock is added as follows. Test report before locking: Average RT (MS): 11, TPS (average/peak): 832/903. Locked test report: Average RT (MS): 12, TPS (average/peak): 825/872. Name explanation: Average RT (MS) RT business response time (Response time), the average RT is the RT average of all APIs, the unit is MS, the smaller the better. The TPS (Average/Peak) TPS system handles transactions per second transaction per second), including the average and peak of the TPS: average: Indicates the average value of the TPS in this scenario during the stress measurement period. Peak value: Indicates that within the pressure measurement period, the highest TPS of the scene is, the larger the better. Figure 2, Figure 3
9. Therefore, whether to add a read lock needs to be measured by yourself. If the read lock is not added, it is recommended to judge whether it is empty when reading the content of the file, and if it is empty, it is necessary to find a way to deal with it additionally.


