![]() |
![]() |
| http://kurepin.ru/php/zametki/flock/ |
|
Как правило, в качестве хранения информации для web-сайтов используют файлы (их еще называют "текстовыми файлами") и SQL-таблицы. Гораздо реже используют таблицы Berkeley DB () и другие форматы хранения информации. При этом почти каждый формат хранения данных имеет свой механизм защиты от сбоев при записи и чтении. Но если в SQL подобный механизм реализован на уровне самого SQL-движка, то в случае с текстовыми файлами вся ответственность за сохранность информации возлагается на нас, на программистов. В PHP существует крайне полезная функция , которая в состоянии обезопасить ваши текстовые файлы от возможного повреждения данных в момент конкурентного (одновременного) обращения к ним. К моему великому сожалению, данную функцию почти всегда опускают в скриптах, полагаясь на современную скорость записи на диск. Чаще всего это срабатывает, но не до бесконечности. Рано или поздно наступает момент, когда два пользователя одновременно нажимают кнопку "сохранить", и два экземпляра одного и того же скрипта пытаются одновременно произвести две записи в один и тот же файл. Например, это могут быть две записи в гостевую книгу сайта. Результат — непредсказуем: от неудачного сохранения новой записи до краха всего файла гостевой книги. А обезопасить себя от подобных ошибок — пара пустяков. Функция flock() создает для файла флаг, указывающий на то, что с файлом идет работа. При этом другой скрипт или другая программа, умеющая распознавать подобный флаг, сделает соответствующие выводы и содержимого файла не нарушит. На примере это выглядит так. Предположим, нам нужен скрипт, который дописывает в конец файла example.txt содержимое переменной $str . Что пишут в подобном случае:
if(!$w=fopen("example.txt","a+")) die "can't open file for append...";
fwrite($w,$str."\n");
fclose($w);
А так это должно быть написано с использованием захвата файлов:
if(!$w=fopen("example.txt","a+")) die "can't open file for append...";
flock($w,2);
fwrite($w,$str."\n");
flock($w,3);
fclose($w);
Вот этот скрипт уже будет работать с файлом безопасно. И если несколько экземпляров данного скрипта захотят произвести запись в файл, то они сделают это по очереди, не толкаясь и не пихая все в одну кучу. Согласитесь, не слишком большие затраты для обеспечения безопасности ваших данных. Теперь о циферках, которые указываются в параметрах flock(), вместе с указателем на файл. 1 — захват файла для чтения. Этот вид захвата говорит другим программам, что файл в данный момент читается. Этот захват не считается "монопольным", и другие программы в лобой момент могут начать чтение данного файла. А если необходимо сделать запись в файл, то fopen() сначала дождется своей очереди, после чего откроет файл для записи: 2 — захват файла для записи. Этот вид захвата называется "монопольным", т.к. доступ к файлу всем другим программам запрещен. 3 — освобождение файла. Вызов flock с параметром "3" освобождает файл от захвата. Не забывайте вызывать flock() с этим параметром, когда закончили работать с файлом. Следует помнить, что функция flock() возымеет действие на файл только в том случае, если она применяется к открытому файлу. На закрытый файл данная функция наложить захват не может. Другими словами, функция flock() с параметром 1 или 2 должна вызываться после открытия файла (fopen()), а flock() с параметром 3 следует вызывать перед его закрытием (fclose()). Более точное описание функции flock() вы можете найти на странице рук-ва: http://www.php.net/manual/en/function.flock.php. 09.03.01 |