PHP lock text file for editing?

£可爱£侵袭症+ 提交于 2019-12-06 02:03:50

问题


I've got a form that writes its input to a textfile. Would it be possible to lock a text file for editing, and perhaps give a friendly message "the file is edited by another user, please try again later."

I'd like to avoid conflicts if the file has multiple editors at the same time.

Here's how the entry is currently 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?


回答1:


You can use flock() function to lock the file. For more see this

Something like:

   <?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
      } 
   ?> 



回答2:


In order of desirability:

  1. Use a database.
  2. Use more than one text file.
  3. 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;
}



回答3:


You can use PHP's flock function to lock a file for writing, but that lock won't persist across web requests and doesn't work on NFS mounts (at least in my experience).

Your best be may be to create a token file in the same directory, check for its existence and report an error if it exists.

As with any locking scheme, you're going to have race conditions and locks that remain after the operation has completed, so you'll need a way to mitigate those.

I would recommend creating a hash of the file before editing and storing that value in the lock file. Also send that hash to the client as part of the edit form (so it comes back as data on the commit request). Before writing, compare the passed hash value to the value in the file. If they are the same, commit the data and remove the lock.

If they are different, show an error.




回答4:


You could try flock — Portable advisory file locking ?

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




回答5:


I would just use a simple 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?



来源:https://stackoverflow.com/questions/15435619/php-lock-text-file-for-editing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!