Я задал вопрос раньше ( как сохранить этот счетчик от реселлера на уровне 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;
Я не хотел предполагать, что знаю, какие изменения внесены в этот код, поэтому я оставляю еще один вопрос. EDIT. Какие изменения я должен сделать, чтобы избежать исключения исключительной блокировки файла, если $ 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;
EDIT – Кажется, это работает для меня:
$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;
Правильно ли это выглядит?
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;
Лучший способ, которым я могу это сделать, – открыть файл для чтения с помощью блокировки, отличной от эксклюзивной. вы можете выполнить требуемые проверки, и если счетчик превысит значение $ reset, вы можете закрыть файл, снова открыть его, но на этот раз с исключительной блокировкой для записи. Другой способ просто не использовать эксклюзивный замок. Вы могли бы изучить очень хорошие классы flatfile, в которых были проверены механизмы блокировки.
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;
Не знаю, если это поможет, так как ваш вопрос по-прежнему непрозрачен. Я не буду отвечать на комментарии.