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');
}
精彩评论