flock

(PHP 4, PHP 5, PHP 7, PHP 8)

flockПортируемая консультативная блокировка файлов

Описание

flock(resource $stream, int $operation, int &$would_block = null): bool

flock() позволяет осуществить простую модель чтения/записи, которая может быть использована практически на любой платформе (включая большинство вариантов Unix и даже Windows).

Блокировка также снимается с помощью fclose() или когда stream собирается сборщиком мусора.

PHP поддерживает портируемый способ консультативной блокировки (advisory locking) полностью всего файла (что означает, что все программы, осуществляющие доступ к файлу, должны использовать один и тот же способ блокировки, иначе блокировка не будет работать). По умолчанию данная функция будет ждать получения блокировки; это поведение можно изменить с помощью описанного ниже параметра LOCK_NB.

Список параметров

stream

Указатель (resource) на файл, обычно создаваемый с помощью функции fopen().

operation

operation может принимать следующие значения:

  • LOCK_SH для получения разделяемой блокировки (чтение).
  • LOCK_EX для получения эксклюзивной блокировки (запись).
  • LOCK_UN для снятия блокировки (разделяемой или эксклюзивной).

Также возможно добавить константу LOCK_NB в качестве битовой маски к любой из вышеуказанных операций, если flock() не должна блокироваться во время попытки блокировки.

would_block

Необязательный третий параметр будет установлен в 1, если блокировка будет блокирующей (код ошибки EWOULDBLOCK).

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример использования функции flock()

<?php

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

if (
flock($fp, LOCK_EX)) { // выполняем эксклюзивную блокировку
ftruncate($fp, 0); // очищаем файл
fwrite($fp, "Что-нибудь пишем сюда\n");
fflush($fp); // очищаем вывод перед отменой блокировки
flock($fp, LOCK_UN); // снимаем блокировку
} else {
echo
"Не удалось получить блокировку!";
}

fclose($fp);

?>

Пример #2 Использование flock() с параметром LOCK_NB

<?php
$fp
= fopen('/tmp/lock.txt', 'r+');

/* Включаем параметр LOCK_NB в операции LOCK_EX */
if(!flock($fp, LOCK_EX | LOCK_NB)) {
echo
'Не удалось получить блокировку';
exit(-
1);
}

/* ... */

fclose($fp);
?>

Примечания

Замечание:

В Windows flock() использует обязательную (mandatory) блокировку вместо консультативной. Обязательная блокировка также поддерживается на Linux и операционных системах, основанных на System V с помощью стандартного механизма, который предоставляет системный вызов fcntl(): то есть искомый файл должен иметь установленный бит доступа setgid и неустановленный бит группового выполнения. Для корректной работы этой схемы в Linux, файловая система также должна быть смонтирована с опцией mand.

Замечание:

Из-за того, что функции flock() необходим указатель на файл, вам может понадобиться воспользоваться специальным запирающим файлом для того, чтобы ограничить доступ к файлу, который вы намерены очищать, путём его открытия в режиме записи (используя "w" или "w+" в качестве аргумента функции fopen()).

Замечание:

Может быть использована только на дескрипторах локальных файлов, возвращённых функцией fopen(), или файловых дескрипторах пользовательских потоков, реализующих метод streamWrapper::stream_lock().

Внимание

Присвоение другого значения аргументу stream в последующем коде отменит существующую блокировку.

Внимание

В некоторых операционных системах flock() реализован на уровне процессов. При использовании многопоточных серверных API, таких как ISAPI, вы не можете полагаться на flock() для защиты ваших файлов от других PHP-скриптов, которые работают в параллельном потоке на том же сервере!

flock() не поддерживается на старых файловых системах вроде FAT и её производных, так что всегда будет возвращать false в этих окружениях.

Замечание:

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