Как сбросить постоянный счетчик на определенное значение? - PullRequest
2 голосов
/ 09 марта 2011

Ранее я задавал вопрос ( Как предотвратить сброс этого счетчика на 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 ]

2 голосов
/ 09 марта 2011
    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 голос
/ 10 марта 2011

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;

Не знаю, поможет ли это, поскольку ваш вопрос все еще непрозрачен.Я не буду отвечать на комментарии.

1 голос
/ 10 марта 2011

Лучший способ сделать это - открыть файл для чтения с блокировкой, отличной от исключительной. затем вы можете выполнить необходимые проверки и, если число превышает значение $ reset, вы можете закрыть файл, открыть его снова, но на этот раз с эксклюзивной блокировкой для записи. Другой способ - просто не использовать эксклюзивный замок. Вы можете посмотреть очень хорошие классы плоских файлов, которые протестировали механизмы блокировки.

...