При работе с файлами, в частности, с процессами чтения / записи, в
определенный момент появляется вопрос о порядке допуска процессов к файлу. Появляется эта ситуация тогда, когда начинается интенсивный обмен данными с файлами и большое количество одновременных запросов на запись и чтение. Решить вопрос очередности возможно, блокируя файл для операций, оставляя доступ только одному процессу в один момент времени. В настоящий момент блокировки различаются на рекомендательную и жесткую. Отличаются они тем, что при рекомендательной блокировке, в особых случаях, процесс может получить доступ к файлу, даже если для него включена блокировка. В жесткой блокировке таких послаблений не предусмотрено. Для Windows-версии PHP установлена поддержка только жесткой блокировки, потому при разработке стоит учитывать этот момент – в других системах выбранный метод может сработать как рекомендательная и некоторые файлы получат доступ не в порядке своей очереди.
Функция блокировки flock()
В настоящий момент в PHP блокировкой занимается функция flock(), которая имеет следующий синтаксис: bool flock(int $f, int $operation [, int &$wouldblock]) Блокировка устанавливается для файла $f (его параметра-переменной, установленной при использовании $f = fopen()) в режиме $operation, которая может принимать следующие значения: - LOCK_SH (альтернативный вариант – 1) – разделяемая блокировка; - LOCK_EX (альтернативный вариант – 2) – исключительная блокировка; - LOCK_UN (альтернативный вариант – 3) – снять блокировку; - LOCK_NB (альтернативный вариант – 4) – константа возвращает программе управление для дальнейших операций, пока действует блокировка. Теперь разберемся, как действует функция flock(). Листинг 35.1. Блокировка файла функцией flock()
//Блокируем файл example.txt на время работы процесса писателя
$file = fopen('example.txt', "a+b") or die("Нет возможности открыть файл..."); if(flock($file, LOCK_EX)){ //Блокировка установлена. В этот момент доступ к файлу имеет только данный процесс-писатель
//Создаем строку, содержающую данные, которые будут записаны в файл
$string = "<p>Новые данные в файле...<p>\r\n";
//Устанавливаем указатель на конец файла
fseek($file, 0, SEEK_END);
//Производим запись в файл
fwrite($file, $string);
1 Лекции курса PHP7 + MySQL с нуля (краткое содержание)
//Здесь закоментирован процесс-читатель, которому закрыт доступ
блокировкой LOCK_EX. Если его раскоментировать, то выведет ошибку конца записи в файл и прекратит выполнение программы с сообщением об ошибке. //$new_string = file_get_contents('example.txt') or die ("<p>Ошибка доступа. Файл заблокирован</p>");
//Открываем доступ к файлу
flock($file, LOCK_UN); }
//Закрываем файл и полностью освобождаем доступ к нему
fclose($file);
//Файл закрыт, следовательно снята блокировка и возможно чтение из файла
$new_string = file_get_contents('example.txt'); echo "<p><b>Строка, записанная в файл:</b> $new_string</p>";
В листинге Вы видите комментарий, содержащий функцию file_get_contents().
Если Вы раскомментируете данную строку, то при запуске программы получите ошибку доступа к файлу, которую выведет конструкция die(). При повторном обновлении страницы браузера программа будет перезапускаться и дописывать в конец файла строку $string.