How to reset a persistent counter at a particular value?
I had asked a question earlier( How to keep this counter from reseting at 100,000? ), and now have a follow-up question.
I have another version of the counter in question that can be told to reset at a certain number, and I would like to make sure that this second version does not have the same problem as the first.
What I have coded now is:
$reset = '10';
$filename4 = "$some_variable/$filename3.txt";
// Open our file in append-or-create mode.
$fh = fopen($filename4, "a+");
if (!$fh)
die("unable to create file");
if ($reset == 'default'){
// Before doing anything else, get an exclusive lock on the file.
// This will prevent anybody else from reading or writing to it.
flock($fh, LOCK_EX);
// Place the pointer at the start of the file.
fseek($fh, 0);
// Read one line from the file, then increment the number.
// There should only ever be one line.
$current = 1 + intval(trim(fgets($fh)));
// Now 开发者_开发知识库we can reset the pointer again, and truncate the file to zero length.
fseek($fh, 0);
ftruncate($fh, 0);
// Now we can write out our line.
fwrite($fh, $current . "\n");
// And we're done. Closing the file will also release the lock.
fclose($fh);
}
else {
$current = trim(file_get_contents($filename4)) + 1;
if($current >= $reset) {
$new = '0';
fwrite(fopen($filename4, 'w'), $new);
}
else {
fwrite(fopen($filec, 'w'), $current);
}
}
echo $current;
I did not want to assume I know what changes to make to this code, so I post another question. EDIT- What changes should I make here to avoid not getting an exclusive lock on the file if $reset is not equal to default? What is the correct way to code this? Would this work?:
$filename4 = "$some_variable/$filename3.txt";
// Open our file in append-or-create mode.
$fh = fopen($filename4, "a+");
if (!$fh)
die("unable to create file");
// Before doing anything else, get an exclusive lock on the file.
// This will prevent anybody else from reading or writing to it.
flock($fh, LOCK_EX);
// Place the pointer at the start of the file.
fseek($fh, 0);
if ($reset == 'default'){
// Read one line from the file, then increment the number.
// There should only ever be one line.
$current = 1 + intval(trim(fgets($fh)));
} else {
// Read one line from the file, then increment the number.
// There should only ever be one line.
$current = 1 + intval(trim(fgets($fh)));
if($current >= $reset) {
$current = '0';
}
else {
// Read one line from the file, then increment the number.
// There should only ever be one line.
$current = 1 + intval(trim(fgets($fh)));
}
}
// Now we can reset the pointer again, and truncate the file to zero length.
fseek($fh, 0);
ftruncate($fh, 0);
// Now we can write out our line.
fwrite($fh, $current . "\n");
// And we're done. Closing the file will also release the lock.
fclose($fh);
echo $current;
EDIT - This seems to be working for me:
$reset = "default";
$filename4 = "counter.txt";
// Open our file in append-or-create mode.
$fh = fopen($filename4, "a+");
if (!$fh)
die("unable to create file");
// Before doing anything else, get an exclusive lock on the file.
// This will prevent anybody else from reading or writing to it.
flock($fh, LOCK_EX);
// Place the pointer at the start of the file.
fseek($fh, 0);
// Read one line from the file, then increment the number.
// There should only ever be one line.
$current = 1 + intval(trim(fgets($fh)));
if ($reset == 'default'){
$new = $current;
} else {
if($current >= ($reset + '1')) {
$new = '1';
}
else {
$new = $current;
}
}
// Now we can reset the pointer again, and truncate the file to zero length.
fseek($fh, 0);
ftruncate($fh, 0);
// Now we can write out our line.
fwrite($fh, $new . "\n");
// And we're done. Closing the file will also release the lock.
fclose($fh);
echo $new;
Does this look right?
if($current >= $reset) {
// here is where you are setting the counter back to zero. comment out
// these lines.
//$new = '0';
//fwrite(fopen($filename4, 'w'), $new);
}
If you simply want a counter that doesn't get reset, try:
$filename4 = "counter.txt";
// Open our file in append-or-create mode.
$fh = fopen($filename4, "a+");
if (!$fh)
die("unable to create file");
// Before doing anything else, get an exclusive lock on the file.
// This will prevent anybody else from reading or writing to it.
flock($fh, LOCK_EX);
// Place the pointer at the start of the file.
fseek($fh, 0);
// Read one line from the file to get current count.
// There should only ever be one line.
$current = intval(trim(fgets($fh)));
// Increment
$new = $current++;
// Now we can reset the pointer again, and truncate the file to zero length.
fseek($fh, 0);
ftruncate($fh, 0);
// Now we can write out our line.
fwrite($fh, $new . "\n");
// And we're done. Closing the file will also release the lock.
fclose($fh);
echo $new;
The best way I can see to do this would be to open the file for reading with a lock other than exclusive. you can then perform your required checks and if the the count exceeds the $reset value, you can close the the file, open it again but this time with the exclusive lock for writing. Another way would simply not to use an exclusive lock. You could look into very good flatfile classes out there which have tested locking mechanisms.
file_put_contents
is already atomic. There is no need for ten lines of file locking code.
<?php
$fn = "$filename3.txt";
$reset = 0; // 0 is equivalent to "default"
//$reset = 10000000;
$count = file_get_contents($fn);
$count = ($reset && ($count >= $reset)) ? (0) : ($count + 1);
file_put_contents($fn, $count, LOCK_EX);
echo $count;
No idea if this is any help, since your question is still opaque. I will not answer comments.
精彩评论