#php #file
#php #файл
Вопрос:
Если я создам программу-счетчик, которая в основном загружает текстовый файл «counter.txt «а затем он считывает файл и, если он содержит число, увеличивает это число на 1, обновляет файл с помощью номера и сохраняет файл.
Код для вышеупомянутой программы отлично работает, скажем, для 1 выполнения в секунду, но проблема начинается, когда время выполнения становится очень высоким, например, 100 в секунду.
Проблема, с которой я сталкиваюсь, заключается в том, что содержимое файла иногда стирается, а иногда счетчик считает неправильно. Допустим, я выполняю 100 исполнений в секунду, но количество увеличится только на 10. Я определенно уверен, что все выполнения завершены, потому что каждое выполнение записывает файл после увеличения числа, и в другом каталоге записано 100 файлов для количества выполнений, но количество в увеличивается только на 10.
<?php
$File = "counter.txt";
$handle = fopen($File, 'r ') ;
$data = fread($handle, 512) ;
$count = $data 1;
fseek($handle, 0) ;
fwrite($handle, $count) ;
fclose($handle) ;
?>
Комментарии:
1. Вам необходимо предотвратить одновременное чтение / запись в файл несколькими экземплярами вашего скрипта. Это можно сделать с помощью блокировок или блокировки файлов. Смотрите php.net/manual/en/function . flock.php
Ответ №1:
Проблема в том, что два файла считаются одновременно. Счетчик не будет установлен должным образом. Вы должны убедиться; доступ к файлу осуществляется только один раз за раз.
Process1: Reads File and gets 0
Process1: Increments 0 to 1
Process2:Reads File and gets 0
Process1: Writes 1 to File
Process2: Increments 0 to 1
Process2: Write 1 to File
Ответ №2:
Привет, @MasterCassim прав.
Использование flock
( http://php.net/manual/en/function .flock.php ) для блокировки файла
<?php
//some code here
flock($file_handle, LOCK_EX) // <- Your code will pause here until you get the lock for indefinite amount of time or till your script times out
//some code here
?>
Комментарии:
1. Это также требует проверки, если файл уже заблокирован, если да, подождите некоторое время или верните FALSE .
2. @ott— зачем вам нужна проверка? Проверьте эту строку из PHPDoc — «По умолчанию эта функция будет блокироваться до тех пор, пока не будет получена запрошенная блокировка»
3. Правильно, я не понял блокировку этого вызова.
Ответ №3:
Если вы случайно уже используете БД со своими php-страницами, вы могли бы поместить в нее счетчик, тогда у вас был бы простой оператор обновления SET counter = counter 1
.