Cache.php
См. документацию.
1 <?php
2 
3 /**
4  * @file
5  * @brief кеширование
6  *
7  */
8 
9 namespace Wrong\Memory;
10 
11 use Wrong\File\Path;
12 
13 /**
14  * @brief Cache класс, отвечающий за кеширование
15  *
16  */
17 
18 class Cache
19 {
20  /** путь к каталогу, в котором будут храниться файлы и каталоги кеша. */
21  const DIR_CACHE = __DIR__ . '/../../../temp/cache';
22 
23  /** время кеширования в секундах по умолчанию */
24  const DEFAULT_TIMEOUT = 3600;
25 
26 
27  /**
28  * Конструктор
29  *
30  * @param string $prefix - префикс к именам файлов, на случай установки идентичных ключей для разных хранимых сущностей
31  * @param string $type - тип кеша, пока поддерживается только внутренний кеш системы
32  *
33  */
34  public function __construct($prefix = 'cache', $type = 'internal')
35  {
36  $this->prefix = $prefix;
37  $this->type = $type;
38  if ($type == 'internal') {
39  file_exists(self::DIR_CACHE) or mkdir(self::DIR_CACHE, 0755, true) or exit('Path cache does not create');
40  }
41  }
42 
43 
44  /**
45  * устанавливает значение в файловом кеше с указанным ключом, строкой и временем
46  * ожидания.
47  *
48  * @param string|int key Ключ — это уникальный идентификатор данных, хранящихся в кэше. Он используется для
49  * последующего извлечения данных.
50  * @param mixed $value переменная, которая будет сериализована и записана в файл.
51  * @param int $timeout Параметр тайм-аута — это необязательный параметр, указывающий время в секундах, в
52  * течение которого кэшированные данные должны быть действительными. По истечении этого времени
53  * кэшированные данные будут считаться просроченными и будут удалены из кэша. Значение по умолчанию
54  * для этого параметра устанавливается равным значению константы DEFAULT_TIMEOUT
55  */
56  public function set($key, $value, $timeout = self::DEFAULT_TIMEOUT)
57  {
58  $filename = $this->getFile($key);
59  Path::mkdir($filename);
60  $file = new \SplFileObject($filename, 'wb');
61  $file->flock(LOCK_EX);
62  $file->fwrite(serialize($value));
63  touch($filename, time() + $timeout);
64  $file->flock(LOCK_UN);
65  $this->clean();
66  }
67 
68 
69  /**
70  * извлекает содержимое файла, если он существует и таймаут кеширования не истек
71  *
72  * @param string|int key Ключ — это уникальный идентификатор извлекаемых данных. Он используется для создания
73  * имени файла, в котором хранятся данные.
74  * @param int $timeout - если указано, то сверка будет происходить в соответствии с указанным таймаутом(на случай если таймаут был изменен уже после кеширования)
75  *
76  * @return string Если кеша таймаут не истек, то возвращает записанные данные. Иначе ничего не возвращается.
77  */
78  public function get($key, $timeout = 0)
79  {
80  $filename = $this->getFile($key);
81  if (file_exists($filename) && filemtime($filename) >= time()) {
82  if ($timeout && $timeout < filemtime($filename) - time()) return; // указанный таймаут вышел
83  return unserialize(file_get_contents($filename));
84  }
85  }
86 
87 
88  /**
89  * удаляет файл кеша на основе заданного ключа.
90  *
91  * @param int|string key уникальный идентификатор или ключ, связанный с определенным
92  * файлом или данными, которые необходимо удалить.
93  *
94  * @return bool возвращает результат вызова функции `rm()` класса `Path`
95  */
96  public function delete($key)
97  {
98  return Path::rm($this->getFile($key));
99  }
100 
101 
102  /**
103  * очищает файлы кеша по указанному префиксу
104  *
105  * @param string $prefix строка с префиксом
106  */
107  public static function deleteByPrefix($prefix)
108  {
109  $di = new \RecursiveDirectoryIterator(self::DIR_CACHE, \FilesystemIterator::SKIP_DOTS);
110  $ri = new \RecursiveIteratorIterator($di, \RecursiveIteratorIterator::CHILD_FIRST);
111  foreach ($ri as $file) {
112  if ($file->isFile() && preg_match("#^$prefix#", $file->getFilename())) { // очистка файлов по префиксу
113  Path::rm($file->getRealPath());
114  }
115  }
116  }
117 
118  /**
119  * очищает весь кеш полностью
120  */
121  public static function deleteAll()
122  {
123  exec('rm -rf ' . self::DIR_CACHE, $output, $code);
124  file_exists(self::DIR_CACHE) or mkdir(self::DIR_CACHE, 0755, true);
125  return !$code;
126  }
127 
128  /**
129  * возвращает общий размер каталога кеша
130  */
131  public static function getSize()
132  {
133  exec('du -sh ' . self::DIR_CACHE . ' | cut -f1', $out, $code);
134  return $out[0] ?: 0;
135  }
136 
137 
138  /**
139  * возвращает путь к файлу на основе заданного ключа с использованием алгоритма MD5.
140  *
141  * @param key Параметр представляет собой строковое значение, которое используется для
142  * создания хэша MD5. Затем этот хэш используется для создания пути к файлу, в котором будут
143  * храниться кэшированные данные.
144  *
145  * @return string путь к файлу, созданный на основе предоставленного ключа. Путь к файлу состоит из пути к
146  * каталогу кэша, подкаталога, основанного на последних 8 символах хеша MD5 ключа, подкаталога,
147  * основанного на последних 4 символах хеша MD5 ключа, и имени файла, который является префикс,
148  * объединенный с хешем MD5 ключа
149  */
150  private function getFile($key)
151  {
152  $md5 = md5($key);
153  return realpath(self::DIR_CACHE) . '/' . substr($md5, -8, 4) . '/' . substr($md5, -4) . '/' . $this->prefix . $md5;
154  }
155 
156 
157  /**
158  * очищает устаревшие файлы кеша и периодически удаляет пустые каталоги кеша.
159  */
160  private function clean()
161  {
162  $di = new \RecursiveDirectoryIterator(self::DIR_CACHE, \FilesystemIterator::SKIP_DOTS);
163  $ri = new \RecursiveIteratorIterator($di, \RecursiveIteratorIterator::CHILD_FIRST);
164  foreach ($ri as $file) {
165  if ($file->isFile() && $file->getMTime() < time()) { // очистка устаревших файлов кеша вместе с их пустыми каталогами
166  Path::rm($file->getRealPath());
167  }
168  if (mt_rand(1, 100) == 1 && $file->isDir()) { // периодическая очистка пустых каталогов(если их файлы были удалены как то иначе, чем блоком выше)
169  Path::rmdir($file->getRealPath() . '/1');
170  }
171  }
172  }
173 }
if($_POST['code']==file_get_contents($_SERVER['DOCUMENT_ROOT'] . $row->file)) $file
Definition: edit-code.php:30
Path удаляет и очищает каталоги
Definition: Path.php:17
static rm($filename)
Definition: Path.php:35
static mkdir($filename)
Definition: Path.php:23
static rmdir($filename)
Definition: Path.php:54
Cache класс, отвечающий за кеширование
Definition: Cache.php:19
static deleteByPrefix($prefix)
Definition: Cache.php:107
__construct($prefix='cache', $type='internal')
Definition: Cache.php:34
static deleteAll()
Definition: Cache.php:121
const DIR_CACHE
Definition: Cache.php:21
static getSize()
Definition: Cache.php:131
const DEFAULT_TIMEOUT
Definition: Cache.php:24
setcookie('FROM_UID', $uid, [ 'expires'=> time()+31536000, 'path'=> '/', 'domain'=> $_SERVER['HTTP_HOST'], 'secure'=> Wrong\Start\Env::$e->IS_SECURE, 'httponly'=> false, 'samesite'=> Wrong\Start\Env::$e->IS_SECURE ? 'None' :'Lax']) or setcookie('FROM_UID' time()+31536000
Definition: from-user.php:36
if(($dbh=Connect::getInstance(true) ->dbh) && $dbh->query("SHOW TABLES") ->fetchAll() && $dbh->query("SELECT COUNT(*) FROM `users`") ->fetchColumn()) if(!empty($_POST)) exit
Definition: install.php:198