У меня есть форма, которая записывает свой вход в текстовый файл. Можно ли заблокировать текстовый файл для редактирования и, возможно, дать дружеское сообщение «файл отредактирован другим пользователем, повторите попытку позже».
Я бы хотел избежать конфликтов, если файл имеет несколько редакторов одновременно.
Вот как добавляется запись.
$ content = file_get_contents ("./ file.csv"); $ fh = fopen ("./ file.csv", "w"); fwrite ($ fh, $ date_yy. '-'. $ date_mm. '-'. $ date_dd. '|'. $ address. '|'. $ person. '|'. $ time_hh. ':'. $ time_mm) ; fwrite ($ fh, "\ n". $ content); fclose ($ ФХ);
Есть предположения?
Вы можете использовать функцию flock()
для блокировки файла. Подробнее см.
Что-то вроде:
<?php $content = file_get_contents("./file.csv"); $fp = fopen("./file.csv", "w"); // open it for WRITING ("w") if (flock($fp, LOCK_EX)) { // do your file writes here fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm); fwrite($fh, "\n" . $content); fclose($fh); flock($fh, LOCK_UN); // unlock the file } ?>
В порядке желательности:
например:
$lockwait = 2; // seconds to wait for lock $waittime = 250000; // microseconds to wait between lock attempts // 2s / 250000us = 8 attempts. $myfile = '/path/to/file.txt'; if( $fh = fopen($myfile, 'a') ) { $waitsum = 0; // attempt to get exclusive, non-blocking lock $locked = flock($fh, LOCK_EX | LOCK_NB); while( !$locked && ($waitsum <= $lockwait) ) { $waitsum += $waittime/1000000; // microseconds to seconds usleep($waittime); $locked = flock($fh, LOCK_EX | LOCK_NB); } if( !$locked ) { echo "Could not lock $myfile for write within $lockwait seconds."; } else { // write out your data here flock($fh, LOCK_UN); // ALWAYS unlock } fclose($fh); // ALWAYS close your file handle } else { echo "Could not open $myfile"; exit 1; }
Вы можете использовать функцию flock PHP для блокировки файла для записи, но эта блокировка не будет сохраняться через веб-запросы и не будет работать с монтированием NFS (по крайней мере, по моему опыту).
Лучше всего будет создать токен-файл в том же каталоге, проверить его существование и сообщить об ошибке, если он существует.
Как и в случае любой схемы блокировки, у вас будут условия гонки и блокировки, которые остаются после завершения операции, поэтому вам понадобится способ их устранения.
Я бы рекомендовал создать хэш файла перед редактированием и сохранением этого значения в файле блокировки. Также отправьте этот хеш клиенту как часть формы редактирования (так что он возвращается как данные в запросе фиксации). Перед записью сравните прошедшее значение хэша с значением в файле. Если они совпадают, зафиксируйте данные и удалите блокировку.
Если они разные, то покажите ошибку.
Вы можете попробовать flock — Portable advisory file locking
?
Я бы просто использовал простое целое число или что-то в этом роде.
$content = file_get_contents("./file.csv"); $fh = fopen("./file.csv", "w"); $status = 1; ... if($status == 1){ fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm); fwrite($fh, "\n" . $content); fclose($fh); $status = 0; } else echo "the file is edited by another user, please try again later.";
Это то, что вы имели ввиду?