Регистрация Войти
Войти через VK Войти через FB Войти через Google Войти через Яндекс
Войти через VK Войти через FB Войти через Google Войти через Яндекс
Поиск по сайту
Блокировщик файлов
Класс - блокировщик файлов, может использоваться при необходимости любых блокировок исполняемых скриптов-потоков и/или их ограничения. Т.е. гарантированно можно использовать какой то скрипт лишь в 1 поток, несмотря на множество запросов к нему. Либо запрещать другие потоки на уровне каждого отдельного пользователя используя в качестве ключа его идентификатор.
Пример использования:
Locker::lock('my-any-key')); // возвращает true если блокировка получена и false если поток существует и блокировка ещё не снята
Locker::unlock('my-any-key')); // снимает блокировку установленную текущим процессом
<?php
/**
* Locker блокировщик файлов
*
* отвечает за блокировку файлов, может использоваться при необходимости любых блокировок исполняемых потоков и их ограничения
* usage example:
*
* if (Locker::lock(basename(__FILE__, '.php'))) {
* Locker::unlock(basename(__FILE__, '.php'));
* }
*
*/
class Locker
{
/** путь к каталогу, в котором будут храниться файлы блокировки. */
const LOCK_PATH = __DIR__ . '/../../../temp';
/** префикс файла блокировки. */
const LOCK_PREFIX = 'lock';
/** время блокировки в секундах */
const CLEAN_TIME = 3600;
/** Переменная класса, используется для хранения пути к файлу блокировки. */
private static $path;
/** Используется, чтобы определить, заблокировал ли текущий процесс файл. */
private static $lock = false;
/**
* создает файл с именем блокировки и записывает текущее время плюс максимальное время, в
* течение которого блокировка должна удерживаться в файле.
*
* Если файл уже существует, проверяет, истек ли срок действия блокировки, и если да, то удаляет
* файл и возвращает значение true.
*
* Если срок действия блокировки не истек, возвращается false.
*
* Если файл не существует, создает файл и возвращает true
*
* @param int $id Имя - ключ файла блокировки.
* @param int $max_time Максимальное время удержания блокировки в секундах.
*/
public static function lock($id, $max_time = self::CLEAN_TIME)
{
self::setPath($id);
if (file_exists(self::$path) && self::cleaner()) {
return false;
}
$file = new \SplFileObject(self::$path, 'a+b');
$file->flock(LOCK_EX);
$file->rewind();
$time = $file->fgets();
$file->ftruncate(0);
$file->fwrite(time() + $max_time);
if (!$time) {
touch(self::$path, time() + $max_time);
$file->flock(LOCK_UN);
self::$lock = true;
return true; // блокировка получена
}
$file->flock(LOCK_UN);
return false; // блокировка не получена
}
/**
* создает каталог, если он не существует, а затем устанавливает в self::$path имя файла блокировки
*
* @param Уникальный идентификатор блокировки, который используется для создания имени файла
* блокировки.
*/
private static function setPath($id)
{
try {
file_exists(self::LOCK_PATH) or mkdir(self::LOCK_PATH, 0755);
if (!file_exists(self::LOCK_PATH)) {
throw new \Error('Path does not create');
}
} catch (\Throwable $th) {
exit($th);
}
self::$path = self::LOCK_PATH . '/' . self::LOCK_PREFIX . '-' . $id . '.lock';
file_exists(self::$path) && clearstatcache(true, self::$path);
}
/**
* Удаляет файл блокировки
*
* @param int $id Имя файла блокировки.
* @param bool $forse истинное означает что блокировка будет снята, даже если она не была создана текущим процессом.
*/
public static function unlock($id, $forse = false)
{
self::setPath($id);
if (file_exists(self::$path) && (self::$lock || $forse)) {
unlink(self::$path);
return true;
}
return false;
}
/**
* удаляет любые файлы блокировки, которые старше текущего времени.
*
* @return bool Логическое значение, истинное означает что текущий файл блокировки по прежнему существует.
*/
private static function cleaner()
{
foreach (glob(self::LOCK_PATH . '/' . self::LOCK_PREFIX . '-*.lock') as $path) {
if (filemtime($path) < time() && intval(file_get_contents($path)) < time()) {
unlink($path);
}
}
return file_exists(self::$path);
}
}
Разместил gorlovkamsbt 20.Apr.2023 https://wrong-mvc.com
.
Прокомментировать/Отблагодарить