开发者

Fopen, fread and flock

I need to lock the file, read the data, write to the file and then clos开发者_运维百科e it. The problem that I have is I'm trying to find the correct mode for fopen.

With 'a+' - always append data, with 'w+' truncated all data when open, with 'x+' - fails to lock the file.

This is my code:

$fh_task = fopen($task_file, 'w+');
flock($fh_task, LOCK_EX) or die('Cant lock '.$task_file);
$opt_line = '';
while(!feof($fh_task)){
  $opt_line .= fread($fh_task, 4096);
}
$options = unserialize($opt_line);
$options['procceed']++;
rewind($fh_task);
fwrite($fh_task, serialize($options));
flock($fh_task, LOCK_UN);
fclose($fh_task);


You want 'r+' (or c+ if you're using a newer version of PHP). r+ doesn't truncate (neither does c+), but still allows you to write.

here's an excerpt from when I last worked with these functions:

        /* 
          if file exists, open in read+ plus mode so we can try to lock it 
          -- opening in w+ would truncate the file *before* we could get a lock!
        */

        if(version_compare(PHP_VERSION, '5.2.6') >= 0) {
            $mode = 'c+';
        } else {
            //'c+' would be the ideal $mode to use, but that's only 
            //available in PHP >=5.2.6

            $mode = file_exists($file) ? 'r+' : 'w+';
            //there's a small chance of a race condition here
            // -- two processes could end up opening the file with 'w+'
        }

        //open file
        if($handle = @fopen($file, $mode)) {
            //get write lock
            flock($handle,LOCK_EX);
            //write data
            fwrite($handle, $myData);
            //truncate all data in file following the data we just wrote 
            ftruncate($handle,ftell($handle));
            //release write lock -- fclose does this automatically
            //but only in PHP <= 5.3.2
            flock($handle,LOCK_UN);
            //close file
            fclose($handle);
        }


I believe you want c+. This is similar to r+ except that it will create a file that does not exist. If you don't want to do this, then use r+ instead. Once you open the file, use flock() as needed. You can c+ opens for reading and writing as well. Other than that, I think you can use the same code.

The other answer is correct, but they're using an extra step to determine to use r or w when c will do this automatically.


Frank Farmer's code not better, than your. Between file_exists and fopen other process can do his own manipulations with file.

Create semaphore-file before opening 'task' file.
Something like:

if (($f_sem = @fopen($task_file.'.sem', 'x')))
{
    //your code (with flock)
    fclose($f_sem);
    unlink($task_file.'.sem');
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜