Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fopen, fread and flock

Tags:

file

php

fopen

I need to lock the file, read the data, write to the file and then close 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);
like image 802
Kein Avatar asked Jan 20 '23 23:01

Kein


2 Answers

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);
        }
like image 73
Frank Farmer Avatar answered Jan 22 '23 14:01

Frank Farmer


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.

like image 34
Explosion Pills Avatar answered Jan 22 '23 13:01

Explosion Pills