Итак, начнем с
того, что же такое исключительная блокировка файла и для чего она необходима.
Не секрет, что множество сайтов хранят свою информацию не в базах данных, а в
простых тестовых файлах. Здесь мы не будем спорить, что лучше и хуже, мы просто
поговорим о специфике работы с данными, хранящимися в файлах. Эти данные могут
иметь различные форматы, различные структуры, но так или иначе манипуляцию этими
данными мы должны взять на себя. Нужно четко понимать, что это бывает иногда
сложней, чем кажется на первый взгляд. Действительно, когда Вы тестируете свои
скрипты, все кажется идеальным: информация добавляется, информация удаляется...
Но стоит только начать работу в сети и ситуация может кардинально измениться.
В ситуации, когда со скриптом работает одновременно большое количество людей
очень важно не потерять контроль над операциями работы с файлом. Возможны ситуации,
когда двое или более людей одновременно запросят операции записи в файл и
произойдет серьезный сбой, который повлечет потерю информации. Модель
исключительной блокировки предотвращает подобные ситуации, "разруливая" процессы
, работающие с файлом и не давая им одновременно выполнять опасные операции.
Обычно работа
с файлом (небезопасная модель без блокировки файла) представляет собой
последовательность действий в виде: открытие файла (получение его дескриптора),
работа с содержимым, закрытие файла. И в самом распространенном варианте выглядит
так:
<?
$fp = fopen ("path_to_file","a");//ОТКРЫТИЕ
fputs($fp ,"$data\r\n");//РАБОТА С ФАЙЛОМ
fclose ($fp);//ЗАКРЫТИЕ
?>
Здесь мы открыли
файл в режиме добавления информации в конец файла, записали в него порцию информации
$data и затем закрыли его (Предполагается, что у нас есть права на запись в файл).
Это самое простое и самое первое, что нам могло прийти
в голову и что мы реализовали. Если вы уверены, что никаких проблем с файлом не
возникнет или что у вас не так много посетителей, чтобы что-то сломалось, то это
ваше право - можете закрыть статью и жить спокойно! ;) Но нужно что-то делать.
Одним из примеров трагедий может служить сайт http://manlix.ru, в котором постоянно
"падает" форум и/или счетчик посетителей. Я, конечно, не берусь судить, что
только некорректная работа с файлами тому виной, но, по-моему, это очевидно. Пока
число посетителей было сравнительно небольшим, все корректно функционировало, как
только иногда одновременно стало появляться до 10 пользователей одновременно, начались
казусы с счетчиком и форумом. Как же это преодолеть? Оказывается просто, всего лишь
добавив несколько строк в операцию работы с файлами:
<?
$fp = fopen ("path_to_file","a");//открытие
flock ($fp,LOCK_EX);//БЛОКИРОВКА ФАЙЛА
fputs($fp ,"$data\r\n");//работа с файлом
fflush ($fp);//ОЧИЩЕНИЕ ФАЙЛОВОГО БУФЕРА И ЗАПИСЬ В ФАЙЛ
flock ($fp,LOCK_UN);//СНЯТИЕ БЛОКИРОВКИ
fclose ($fp);//закрытие
?>
В данном примере
мы открыли файл для добавления в него информации Предполагается, что у нас есть
права на запись в файл). Затем применили исключительную
блокировку и тем самым сделали наш скрипт единственным процессом, который в текущий
момент имеет доступ к файлу. Блокировка действительна все время от выполнения функции
flock ($fp,LOCK_EX) и до выполнения flock ($fp,LOCK_UN). Между этими функциями
находятся операторы, выполнение которых будет "безопасным" для файла. Другие
процессы смогут получить доступ к файлу не раньше снятия блокировки. Важным
моментом является применение функции fflush ($fp). Транзакции изменения данных
могут быть записаны с специальный файловый буфер и сброшены на диск позже, когда
блокировка будет уже снята и снова будет опасность сбоя в работе. Поэтому данной
функцией мы принудительно записываем изменения на диск, сбрасывая содержимое
буфера. Еще одним не менее важным моментом является, само открытие файла! Мы не
случайно используем режим "a" ("a+"). Если нам будет необходима запись в начало файла
с удалением предыдущего содержимого, то следует воздержаться от применения режима
"w" ("w+"), поскольку очищение файла предполагает удаление не только содержимого,
но и самого файла с последующим созданием аналогичного. Так как этот процесс
будет выполнен до исключительной блокировки, то также существует вероятность сбоя
в работе. В данном случае стоит применять следующий прием :
<?
$fp = fopen ("path_to_file","a");//открытие
flock ($fp,LOCK_EX);//блокировка файла
ftruncate ($fp,0);//УДАЛЯЕМ СОДЕРЖИМОЕ ФАЙЛА
fputs($fp ,"$data\r\n");//работа с файлом
fflush ($fp);//очищение файлового буфера и записьв файл
flock ($fp,LOCK_UN);//снятие блокировки
fclose ($fp);//закрытие
?>
Здесь мы открыли
файл для записи в него, затем применили исключительную блокировку, и только уж
потом применили функцию ftruncate ($fp,0) которая выполнила так необходимую нам
очистку файла от содержимого. Вот вроде бы и все, что я хотел вам для начала
рассказать! Успехов Вам в нашем нелегком труде! До новых встреч, до новых статей!
|