(PHP 4, PHP 5, PHP 7, PHP 8)
flock — Портируемая консультативная блокировка файлов
$stream
, int $operation
, int &$would_block
= null
): boolflock() позволяет осуществить простую модель чтения/записи, которая может быть использована практически на любой платформе (включая большинство вариантов 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, если процесс блокировки открывает файл во второй раз, он не может получить доступ к файлу через второй дескриптор, пока он не разблокирует файл.