views:

1787

answers:

4

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?

+7  A: 

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.

Kyle Cronin
+1  A: 

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)

Josh Smeaton
+1  A: 

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.

Kent Fredric
+5  A: 

You should put a lock on the file

<?php

$fp = fopen("/tmp/lock.txt", "w+");

if (flock($fp, LOCK_EX)) { // do an exclusive lock
    fwrite($fp, "Write something here\n");
    flock($fp, LOCK_UN); // release the lock
} else {
    echo "Couldn't lock the file !";
}

fclose($fp);

?>

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

andy.gurin