Writing into a file and how to lock it

I want to write into a file small piece of data but while writing i don’t want other process to access it. I would like to get an opinion from the community about this code.

$file_path = 'data_to_write.json';

// Check if the file exists
if (!file_exists($file_path)) {
  // make empty file if not there
  file_put_contents($file_path, '{}');
}

// Create a lock file
$my_lock_file = 'my_data.lock';

// Wait until release
while (file_exists($lock_file)) {
  usleep(500000); // Wait a bit
}

// Create a lock file since i am writing to it
file_put_contents($lock_file, '');

// Write data to file
file_put_contents($file_path, json_encode($data_toWrite));

// Remove the lock file 
unlink($lock_file);

Any critique would be great or better way to do this

PHP has a function to (Somewhat) do this. https://www.php.net/manual/en/function.flock.php

Benefit being it will release the lock on garbage collection, which means if your script takes a nosedive while its holding the lock, you dont end up with a permanently locked file (until you manually delete the lock)

Your intention is to append $data_toWrite to the file $file_path, correct?

If so, I think you can just call

file_put_contents($file_path, json_encode($data_toWrite),LOCK_EX);

https://www.php.net/manual/en/function.file-put-contents.php

1 Like

Good call, but if you want to append you’d need that flag too. FILE_APPEND|LOCK_EX

Urp, yes. I had my defaults wrong anyway. His code does NOT append, it overwrites, so by dumb mistake, I think leaving off FILE_APPEND is actually what he does want. But I may be assuming too much :slight_smile:

1 Like

Well, now OP knows both ways! :smiley:

1 Like

yes i want to always overwrite

@m_hutley can you please comment on why this is not working. I don’t understand that when using .txt file works fine but when i block that and use .json file browser just keeps hanging and doesn’t complete? any guidance, suggestions would be greatly appreciated

//$fp = fopen("my_data.json", "r+");
$fp = fopen("lock.txt", "r+");

if (flock($fp, LOCK_EX)) {  // acquire an exclusive lock
    ftruncate($fp, 0);      // truncate file
    fwrite($fp, "write something");
    fflush($fp);            // flush output before releasing the lock
    flock($fp, LOCK_UN);    // release the lock
} else {
    echo "Couldn't get the lock!";
}

fclose($fp);

echo "Done";

Works fine for me… you sure nothing else has the json file open?

yes i am sure…is there a way to get any output error log to see why it is spinning. apache log file doesnt show me anything

flock will block until it can achieve a lock. So if something’s got the file open and reading, it wont be able to acquire an exclusive lock, and it will keep waiting until it can.

i closed by VSC editor and that didn’t help and closed the browser and tried again still nothing. I rebooted the computer and now it works. How would I find what was holding/ locking the file?

Depends on what OS you’re on. I will assume Windows, because 70% of the world uses Windows.

Process explorer can find out what processes are locking a file; use the target thing on the target file and it will identify what process(es) have it open.

2 Likes