PHP and concurrent file access

后端 未结 4 1284
我在风中等你
我在风中等你 2020-12-14 22:28

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 i

相关标签:
4条回答
  • 2020-12-14 22:49

    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

    0 讨论(0)
  • 2020-12-14 23:02

    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.

    0 讨论(0)
  • 2020-12-14 23:02

    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.

    0 讨论(0)
  • 2020-12-14 23:12

    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)

    0 讨论(0)
提交回复
热议问题