Home > Net >  Will user update or overwriting file before other session done in PHP?
Will user update or overwriting file before other session done in PHP?

Time:05-26

I'm currenty working on php that page settings and data stored on json file. Which the user able to modify the file, the explanation about the outdated file, if there was 2 user using these function at the same time.

 function updateConfig() {
   // get
   // edit
   // save
 }

The first user call the first, but just before the first save the file, the second user get the file, which it make the second user get the unmodified file from first user (outdated), so after the the second user modify the file, the first user work will be unsaved or overwrite directly by the second user.

The logic that im understanding that the PHP run in single executable on the server, different with Javascript, that run on users. So the instruction or the code will be executed by its order right? one by one? user by user? the function that i writing are all sync, no async function.

Is there any posibility to this overwriting thing happend? I read few article about PHP multi threading and something similiar but i seems doesnt get the answer, is there any reference that i could ready? or probably some PHP configuration that i could set to prevent this?

CodePudding user response:

You should lock the file. This way you can be sure that they can't have access (write access) to the file at the same time:

$file = fopen("test.txt","w ");

// exclusive lock
if (flock($file,LOCK_EX)) {
  fwrite($file,"....");
  fflush($file);

  // release lock
  flock($file,LOCK_UN);
} else {
  echo "Error locking file!";
}
fclose($file);

On the other hand, you can use databases. They implement the locking mechanism out of the box for you.

CodePudding user response:

PHP is synchronous unless you specify otherwise, so any write operations should be queued and prevent the vast majority of write conflicts. To be extra safe, I am copying an answer [link] that explains how to do so below:


File access is simultaneous but you can use flock to block other handles from accessing the file while you perform your read/write operations. It sounds like the best solution to your problem would be to use PDO and SQLite (if available). This way you have the database handle all locking for you but do not need a dedicated database server. SQLite is entirely file based.

If SQLite is not available, you'll want to make use of flock's LOCK_EX operation, this will only allow one write stream to access the file at a time, e.g.

// create the file handle
$hnd = fopen($destpath, 'ab ');

if ($isReadOperation) {
    // shared lock - simultaneous reads can happen at one time
    flock($hnd, LOCK_SH);

    // perform your read operation
} else {
    // exclusive lock - only one write can occur at a time after all shared locks are released
    flock($hnd, LOCK_EX);

    // perform your read/write operation
}

// release the lock
flock($hnd, LOCK_UN);

// release the file handle
fclose($hnd);

CodePudding user response:

PHP usually runs synchronously. So for a request by one user everything is processed in order. But: a request by a second user also runs synchronously, but in parallel to the first user.

This can be a problem if both users are trying to change different things in the same file. For example, let's say you have the following JSON file:

{
    "setting1": 123,
    "setting2": 456
}

If you have two users, where user one wants to change setting1 to 234 and user two wants to change setting2 to 567, you could have an overlap:

  User one        
      |           User two
      v               |
PHP process 1         v
      |         PHP process 2
      v               |
  Read file           |
setting1=123          |
setting2=456          v
      |           Read file
      |         setting1=123
      |         setting2=456
      v               |
   Changes            v
setting1=234       Changes
setting2=456    setting1=123
      |         setting2=567
      v               |
  Write file          v
                  Write file

By the time user two reads the JSON file, user one has not yet written their changes so they will read setting1 as 123.

To avoid this, you can implement file locking, you can block the second user's request until the first user is finished:

  User one        
      |           User two
      v               |
PHP process 1         v
      |         PHP process 2
      v               |
  Lock file           v
      |           Lock file (wait for lock release by process 1)
      v               |
  Read file           |
setting1=123          |
setting2=456          |
      |               |
      v               |
   Changes            |
setting1=234          |
setting2=456          |
      |               |
      v               |
  Write file          |
      |               |
      v               |
 Unlock file          v
                  Lock file
                      |
                      v
                  Read file
                setting1=234
                setting2=456
                      |
                      v
                   Changes
                setting1=234
                setting2=567
                      |
                      v
                  Write file
                      |
                      v
                 Unlock file

Now, the changes made by both users are persisted.

  • Related