Php block text file for editing?

I have a form that writes its input to a text file. Is it possible to lock the text file for editing and, possibly, give a friendly message "the file was edited by another user, try again later."

I would like to avoid conflicts if the file has several editors at the same time.

Here's how the record is added.

  $ content = file_get_contents ("./ file.csv");
 $ fh = fopen ("./ file.csv", "w");
 fwrite ($ fh, $ date_yy. '-'. $ date_mm. '-'. $ date_dd. '|'. $ address. '|'. $ person. '|'. $ time_hh. ':'. $ time_mm) ;
 fwrite ($ fh, "\ n". $ content);
 fclose ($ fh); 

Any thoughts?

+6
source share
5 answers

You can use the flock() function to lock the file. See this for more details.

Sort of:

  <?php $content = file_get_contents("./file.csv"); $fp = fopen("./file.csv", "w"); // open it for WRITING ("w") if (flock($fp, LOCK_EX)) { // do your file writes here fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm); fwrite($fh, "\n" . $content); fclose($fh); flock($fh, LOCK_UN); // unlock the file } ?> 
+4
source

In order of desirability:

  • Use the database.
  • Use multiple text files.
  • Use locks :

eg:

 $lockwait = 2; // seconds to wait for lock $waittime = 250000; // microseconds to wait between lock attempts // 2s / 250000us = 8 attempts. $myfile = '/path/to/file.txt'; if( $fh = fopen($myfile, 'a') ) { $waitsum = 0; // attempt to get exclusive, non-blocking lock $locked = flock($fh, LOCK_EX | LOCK_NB); while( !$locked && ($waitsum <= $lockwait) ) { $waitsum += $waittime/1000000; // microseconds to seconds usleep($waittime); $locked = flock($fh, LOCK_EX | LOCK_NB); } if( !$locked ) { echo "Could not lock $myfile for write within $lockwait seconds."; } else { // write out your data here flock($fh, LOCK_UN); // ALWAYS unlock } fclose($fh); // ALWAYS close your file handle } else { echo "Could not open $myfile"; exit 1; } 
+2
source

You can use the PHP flock function to lock the file for writing, but this lock will not be saved on the Internet of requests and does not work on NFS mounts (at least in my experience).

It is best to create a text file in the same directory, check its existence and report an error if it exists.

As with any blocking scheme, you will have race and blocking conditions that remain after the operation is completed, so you will need a way to reduce them.

I would recommend creating a hash of the file before editing and saving this value in the lock file. Also send this hash to the client as part of the edit form (so that it returns as data in the commit request). Before writing, compare the past hash value with the value in the file. If they match, commit the data and remove the lock.

If they are different, show a mistake.

+1
source

Can you try flock β€” Portable advisory file locking ?

http://php.net/manual/en/function.flock.php

0
source

I would just use a prime integer or something like that.

  $content = file_get_contents("./file.csv"); $fh = fopen("./file.csv", "w"); $status = 1; ... if($status == 1){ fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm); fwrite($fh, "\n" . $content); fclose($fh); $status = 0; } else echo "the file is edited by another user, please try again later."; 

Is that what you mean?

-1
source

All Articles