Как читать и писать в файл, гарантируя, что файл заблокирован?

Я хочу численно увеличить содержимое файла, если последний раз файл был изменен в течение 24 часов, в противном случае сбросить содержимое файла до 1. Однако я хочу, чтобы это продолжало работать независимо от того, сколько пользователей одновременно посещают скрипт ( script всегда нужно выполнять, но следите за тем, чтобы он не перезаписывал/вычислял неправильно - я считаю, что именно здесь используется flock).

Пожалуйста, смотрите код ниже:

$host_limit = 50;
$file = 'timer.txt';
$fh = fopen($file,'r+');
if (flock($fh,LOCK_EX)) {
$content = fgets($fh);
//FILE HAS NOT BEEN MODIFIED IN LAST 24 HOURS
if (strtotime('-24 hours') > filemtime($file)) {
$content = 1;
} else {
$content = ($content + 1);
}
fwrite($fh, $content);
fflush($fh);
flock($fh,LOCK_UN);
}
fclose($fh);

if ($content < $host_limit) {
//do stuff
}

Будет ли вышеизложенное работать так, как я хотел бы (поскольку у меня нет возможности смоделировать то, что я ожидаю протестировать)?


person Stone    schedule 07.03.2015    source источник


Ответы (1)


Вместо использования fopen и fwrite вы можете использовать file_get_contents($file); и file_put_contents($file, $content, LOCK_EX);

Проверьте руководство:

http://php.net/manual/en/function.file-get-contents.php

http://php.net/manual/en/function.file-put-contents.php

person Zencode.dk    schedule 07.03.2015
comment
Не будет ли риск использования file_get_contents в $content, поскольку он не поддерживает LOCK_EX, поэтому может фактически содержать устаревшее содержимое файла? также ожидает ли file_put_contents с LOCK_EX, пока какая-либо предыдущая блокировка не будет разблокирована перед выполнением, или в этом случае она просто не удастся? - person Stone; 07.03.2015
comment
Извините, я, вероятно, неправильно понял .. Вы могли бы перепутать его с вышеупомянутыми file_get_contents и file_put_contents .. Кроме этого, попытайте счастья .. Это не выглядит слишком далеким, но почти невозможно провести стресс-тест самостоятельно .. Может быть, поместить некоторые данные в файл журнала и протестировать его в течение нескольких дней. - person Zencode.dk; 07.03.2015
comment
file_get_contents() не является атомарным, поскольку не учитывает рекомендательные блокировки. - person d_void; 30.08.2017
comment
Это решение, похоже, не работает для меня. Иногда я получаю чтение пустой строки из file_get_contents, несмотря на использование LOCK_EX для file_put_contents. - person Rick; 24.07.2019