Подтвердить что ты не робот

PHP и одновременный доступ к файлам

Я создаю небольшое веб-приложение на PHP, которое хранит некоторую информацию в текстовом файле. Однако этот текстовый файл используется/модифицируется всеми пользователями моего приложения в определенный момент времени и возможен в одно и то же время.

Итак, вопросы есть. Какой был бы лучший способ убедиться, что только один пользователь может вносить изменения в файл в любой момент времени?

4b9b3361

Ответ 1

Вы должны поместить блокировку в файл

<?php

$fp = fopen("/tmp/lock.txt", "w+");

if (flock($fp, LOCK_EX)) { // do an exclusive lock
    fwrite($fp, "Write something here\n");
    flock($fp, LOCK_UN); // release the lock
} else {
    echo "Couldn't lock the file !";
}

fclose($fp);

?>

Взгляните на http://www.php.net/flock

Ответ 2

Мое предложение - использовать SQLite. Он быстрый, легкий, хранится в файле и имеет механизмы предотвращения одновременной модификации. Если вы не имеете дело с существующим файловым форматом, SQLite - это путь.

Ответ 3

Вы можете сделать формат журнала фиксации, как это делает википедия.

Используйте базу данных, и каждое сохраненное изменение создает новую строку в базе данных, что делает предыдущую запись избыточной, с увеличенным значением, тогда вам остается только беспокоиться о том, чтобы блокировать таблицы во время фазы сохранения.

Таким образом, по крайней мере, если 2 одновременных человека могут что-то изменить, оба изменения появятся в истории, и все, что потеряно в войне фиксации, можно скопировать в новую ревизию.

Теперь, если вы не хотите использовать базу данных, вам придется беспокоиться о том, что файл контроля версий поддерживает все видимые файлы.

Вы можете поместить контроль над версией (GIT/MERCURIAL/SVN) в файловую систему, а затем автоматизировать фиксацию во время фазы сохранения,

Псевдокод:

 user->save : 
   getWritelock(); 
   write( $file ); 
   write_commitmessage( $commitmessagefile ); # <-- author , comment, etc 
   call "hg commit -l $commitmessagefile $file " ; 
   releaseWriteLock(); 
 done.

По крайней мере, так, когда 2 человека совершают критические попытки одновременно, ни один из них не потеряется.

Ответ 4

Один файл для многих пользователей на самом деле не должен быть той стратегией, которую вы используете, я не думаю, иначе вам, вероятно, потребуется реализовать единую (глобальную) точку доступа, которая контролирует, будет ли файл в данный момент редактироваться или нет, Аквариумируйте блокировку, сделайте свою модификацию, отпустите блокировку и т.д. Я бы пошел с "Никто не предлагал использовать базу данных (SQLite, если вы не хотите накладных расходов на полностью декодированные РСУБД)