如何将持久计数器重置为特定值?

时间:2011-03-09 20:02:39

标签: php hitcounter

我之前曾问过一个问题(How to keep this counter from reseting at 100,000?),现在有一个跟进问题。

我有另一个版本的计数器可以被告知重置一定数量,我想确保第二个版本没有与第一个版本相同的问题。

我现在编码的是:

$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;

我不想假设我知道对此代码进行了哪些更改,因此我发布了另一个问题。编辑 - 如果$ reset不等于默认值,我应该在这里做些什么改变以避免不对文件进行独占锁定?编码的正确方法是什么?这会有用吗?:

$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;

编辑 - 这似乎对我有用:

$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;

这看起来不错吗?

3 个答案:

答案 0 :(得分:2)

    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);                        
    }

如果您只想要一个无法重置的计数器,请尝试:

$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;                

答案 1 :(得分:1)

我可以看到这样做的最好方法是打开文件以使用除独占之外的锁读取。然后,您可以执行所需的检查,如果计数超过$ reset值,您可以关闭该文件,再次打开它,但这次使用独占锁写入。 另一种方法是不使用独占锁。 您可以查看那些已经测试过锁定机制的非常好的flatfile类。

答案 2 :(得分:1)

file_put_contents已经是原子的。不需要十行文件锁定代码。

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

不知道这是否有任何帮助,因为您的问题仍然不透明。我不会回答评论。