2

I have a php code in which multiple users can edit the form at the same time which is causing a problem to us because the last person who saves the form win the race wiping out other users changes.

Currently, I am using JSON to store all information but I will switch to database soon.

flash
  • 1,455
  • 11
  • 61
  • 132
  • Switching to a database _is_ the solution to this problem. Anything else would just be trying to re-implement a database inside PHP. – Sammitch Mar 23 '20 at 21:41
  • @Sammitch We use both database and json just to store data. Is there any way we can do that in JSON ? I will later definitely switch to database for sure. Probably i am gonna use SQLite. At this moment, I am looking for a short term solution. – flash Mar 23 '20 at 21:43
  • Use [`flock()`](https://www.php.net/manual/en/function.flock.php) to lock the file before you touch it, even to read it. Don't release the lock until you're completely done with it. Embrace the performance degradation of multiple processes contending for the lock. – Sammitch Mar 23 '20 at 21:49
  • Database is the way. You can, if you insist using this (awful) way, write some info like "form opened by XXX at dd-mm-yyyy hh:ii:ss" and then, when the user saves, or when some time past like 5 minutes, you will considered the form is saved by the last user and allow the next one to write on it. – Felippe Duarte Mar 23 '20 at 21:50

3 Answers3

4

you can lock the file or version it. Everytime you save the full version will be saved in database with a timestamp an userid. The give a "live" flag so you can say: this is the live version to publish.

When you have this information you can make nice git features like git diff, git merge if more version exists. :)

bleib gesund.

2

You can stop others to edit the text while the first user (the one that logged in first) is doing it. To do that, you can add another .json file to save the last activity of users in order of their login times. For example let's say user one logged in at 1585844170 (value of time()) and 1s later user2. So at this time we have this content in activity.json

{
    "user1": 1585844170
    "user2": 1585844171
}

By a simple javascript interval (using Ajax) we can update this activity let's say every 1000ms. As a timeout, when we don't get any request for updating this time let's say after 5s we consider that user is gone. So each time that a user sends a request for updating the activity time, he gets a json as a result that says he can start editing yet or not. For example:

{
    "updated": true,
    "editable": false,
    "editingBy": "user1"
}

So when editable is true, we can enable inputs (textareas etc) and let the user to start typing! Also you can show who is editing now!
To understand this better, let's say that user1 is gone (no activity updates for him in last 5s) and now user2 sends an update activity request. In this case user1 will be deleted and user2 is now allowed to edit the text.

{
    "user2": 1585844190
}



Note

1. When you receive a request for editing the text in your php file, you should also check whether the user is the one allowed or not (because javascript can be edited by that user)
2. You can make a function for modifying the activity.json file and run it each time you get a request from a user.

Mohsen Nemati
  • 379
  • 1
  • 11
1

A temporary solution for you I believe would be this since you don't wanna do it on the database.

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

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

fclose($fp);

reference