I have a php script that is executed quite often via ajax and its purpose is to record the time a user was last ‘seen’ on the site (this is for the purpose of availability status in a chat). I decided to write this information to small files because it might be too heavy for the database.
Example:
file_put_contents("100.txt", date('Y-m-d H:i:s'), LOCK_EX);
In 99% of cases this overwrites a file with the same name. I thought that the LOCK_EX flag would lock the file before writing and guarantee it’s either written or not. But it does not appear to be so. I read the file in the following way and just out of curiosity I log every occurrence of it being corrupt (wrong date format):
$timeFormatted = @file_get_contents("100.txt");
if ($timeFormatted !== false && !preg_match('/^20[0-9]{2}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$/', $timeFormatted)) {
// corrupt file - log this event
// ...
}
Occasionally, file_get_contents
reads an empty file - empty string is returned. I don’t get partial writes but empty string is certainly not correct. I’ve found that file_put_contents
with FILE_APPEND and LOCK_EX works well in concurrent scenarios - and that’s what I find is most often discussed on other discussion boards. But when I don’t use FILE_APPEND then it becomes problematic. What would you use for atomic file write?