PHP and concurrent file access

I'm building a small web app in PHP that stores some information in a plain text file. However, this text file is used/modified by all users of my app at some given point in time and possible at the same time.

So the questions is. What would be the best way to make sure that only one user can make changes to the file at any given point in time?

Answers


You should put a lock on the file

    $fp = fopen("/tmp/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);

Take a look at the http://www.php.net/flock


My suggestion is to use SQLite. It's fast, lightweight, stored in a file, and has mechanisms for preventing concurrent modification. Unless you're dealing with a preexisting file format, SQLite is the way to go.


You could do a commit log sort of format, sort of how wikipedia does.

Use a database, and every saved change creates a new row in the database, that makes the previous record redundant, with an incremented value, then you only have to worry about getting table locks during the save phase.

That way at least if 2 concurrent people happen to edit something, both changes will appear in the history and whatever one lost out to the commit war can be copied into the new revision.

Now if you don't want to use a database, then you have to worry about having a revision control file backing every visible file.

You could put a revision control ( GIT/MERCURIAL/SVN ) on the file system and then automate commits during the save phase,

Pseudocode:

 user->save : 
   getWritelock(); 
   write( $file ); 
   write_commitmessage( $commitmessagefile ); # <-- author , comment, etc 
   call "hg commit -l $commitmessagefile $file " ; 
   releaseWriteLock(); 
 done.

At least this way when 2 people make critical commits at the same time, neither will get lost.


A single file for many users really shouldn't be the strategy you use I don't think - otherwise you'll probably need to implement a single (global) access point that monitors if the file is currently being edited or not. Aquire a lock, do your modification, release the lock etc. I'd go with 'Nobody's suggestion to use a database (SQLite if you don't want the overhead of a fully decked out RDBMS)


Need Your Help

Echo a blank (empty) line to the console from a Windows batch file

windows batch-file echo

When outputting status messages to the console from a Windows batch file, I want to output blank lines to break up the output. How do I do this?

Is there a way to reduce the spacing between the Action Item Icons on Action Bar?

android

I wanted to reduce the spacing bettween Action Item icons added to the ActionBar. Is there a way we can do this?