1 | <?php |
||||
2 | |||||
3 | namespace Anax\Cache; |
||||
4 | |||||
5 | use Psr\SimpleCache\CacheInterface; |
||||
6 | |||||
7 | /** |
||||
8 | * File based cache in line with PSR-3. |
||||
9 | */ |
||||
10 | class FileCache implements CacheInterface |
||||
11 | { |
||||
12 | /** |
||||
13 | * @var string $cachePath the path to the cache dir. |
||||
14 | * @var int $timeToLive default setting for time to live in seconds. |
||||
15 | */ |
||||
16 | private $cachePath; |
||||
17 | private $timeToLive = 7 * 24 * 60 * 60; |
||||
18 | |||||
19 | |||||
20 | |||||
21 | /** |
||||
22 | * Set the base for the cache path where all items are stored. |
||||
23 | * |
||||
24 | * @param string $path A valid writable path. |
||||
25 | * |
||||
26 | * @return void. |
||||
0 ignored issues
–
show
Documentation
Bug
introduced
by
![]() |
|||||
27 | * |
||||
28 | * @throws \Psr\SimpleCache\CacheException when the path is not writable. |
||||
29 | */ |
||||
30 | public function setPath(string $path) : void |
||||
31 | { |
||||
32 | if (!is_writable($path)) { |
||||
33 | throw new Exception("The path to the cache is not writable."); |
||||
34 | } |
||||
35 | |||||
36 | $this->cachePath = $path; |
||||
37 | } |
||||
38 | |||||
39 | |||||
40 | |||||
41 | /** |
||||
42 | * Set default setting for time to live for a cache item. |
||||
43 | * |
||||
44 | * @param int $timeToLive in seconds. |
||||
45 | * |
||||
46 | * @return void. |
||||
0 ignored issues
–
show
|
|||||
47 | * |
||||
48 | * @throws \Psr\SimpleCache\CacheException when the path is not writable. |
||||
49 | */ |
||||
50 | public function setTimeToLive(int $timeToLive) : void |
||||
51 | { |
||||
52 | $this->timeToLive = $timeToLive; |
||||
53 | } |
||||
54 | |||||
55 | |||||
56 | |||||
57 | /** |
||||
58 | * Fetches a value from the cache. |
||||
59 | * |
||||
60 | * @param string $key The unique key of this item in the cache. |
||||
61 | * @param mixed $default Default value to return if the key does not exist. |
||||
62 | * |
||||
63 | * @return mixed The value of the item from the cache, or $default in case |
||||
64 | * of cache miss. |
||||
65 | * |
||||
66 | * @throws \Psr\SimpleCache\InvalidArgumentException |
||||
67 | * MUST be thrown if the $key string is not a legal value. |
||||
68 | */ |
||||
69 | public function get($key, $default = null) |
||||
70 | { |
||||
71 | $file = $this->filename($key); |
||||
72 | |||||
73 | if (is_file($file)) { |
||||
74 | // if ($age) { |
||||
75 | // $age = filemtime($file) + $this->timeToLive > time(); |
||||
76 | // } |
||||
77 | // |
||||
78 | // if (!$age) { |
||||
79 | // // json |
||||
80 | // // text |
||||
81 | // return unserialize(file_get_contents($file)); |
||||
82 | // } |
||||
83 | |||||
84 | return unserialize(file_get_contents($file)); |
||||
85 | } |
||||
86 | |||||
87 | return $default; |
||||
88 | } |
||||
89 | |||||
90 | |||||
91 | |||||
92 | /** |
||||
93 | * Persists data in the cache, uniquely referenced by a key with an |
||||
94 | * optional expiration TTL time. |
||||
95 | * |
||||
96 | * @param string $key The key of the item to store. |
||||
97 | * @param mixed $value The value of the item to store, |
||||
98 | * must be serializable. |
||||
99 | * @param null|int|\DateInterval $ttl Optional. The TTL value of this |
||||
100 | * item. If no value is sent and |
||||
101 | * the driver supports TTL then the |
||||
102 | * library may set a default value |
||||
103 | * for it or let the driver take care |
||||
104 | * of that. |
||||
105 | * |
||||
106 | * @return bool True on success and false on failure. |
||||
107 | * |
||||
108 | * @throws \Psr\SimpleCache\InvalidArgumentException |
||||
109 | * MUST be thrown if the $key string is not a legal value. |
||||
110 | */ |
||||
111 | public function set($key, $value, $ttl = null) |
||||
112 | { |
||||
113 | $file = $this->filename($key); |
||||
114 | |||||
115 | // json |
||||
116 | // text |
||||
117 | if (!file_put_contents($file, serialize($value))) { |
||||
118 | throw new Exception("Failed writing cache object '$key'."); |
||||
119 | } |
||||
120 | } |
||||
121 | |||||
122 | |||||
123 | |||||
124 | /** |
||||
125 | * Delete an item from the cache by its unique key. |
||||
126 | * |
||||
127 | * @param string $key The unique cache key of the item to delete. |
||||
128 | * |
||||
129 | * @return bool True if the item was successfully removed. False if there was an error. |
||||
130 | * |
||||
131 | * @throws \Psr\SimpleCache\InvalidArgumentException |
||||
132 | * MUST be thrown if the $key string is not a legal value. |
||||
133 | */ |
||||
134 | public function delete($key) |
||||
135 | { |
||||
136 | @unlink($this->filename($key)); |
||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||||
137 | } |
||||
138 | |||||
139 | |||||
140 | |||||
141 | /** |
||||
142 | * Wipes clean the entire cache's keys. |
||||
143 | * |
||||
144 | * @return bool True on success and false on failure. |
||||
145 | */ |
||||
146 | public function clear() |
||||
147 | { |
||||
148 | $files = glob($this->cachePath . "/*"); |
||||
149 | $items = count($files); |
||||
0 ignored issues
–
show
|
|||||
150 | array_map('unlink', $files); |
||||
151 | return true; |
||||
152 | } |
||||
153 | |||||
154 | |||||
155 | |||||
156 | /** |
||||
157 | * Obtains multiple cache items by their unique keys. |
||||
158 | * |
||||
159 | * @param iterable $keys A list of keys that can obtained in a single |
||||
160 | * operation. |
||||
161 | * @param mixed $default Default value to return for keys that do not |
||||
162 | * exist. |
||||
163 | * |
||||
164 | * @return iterable A list of key => value pairs. Cache keys that do not |
||||
165 | * exist or are stale will have $default as value. |
||||
166 | * |
||||
167 | * @throws \Psr\SimpleCache\InvalidArgumentException |
||||
168 | * MUST be thrown if $keys is neither an array nor a Traversable, |
||||
169 | * or if any of the $keys are not a legal value. |
||||
170 | */ |
||||
171 | public function getMultiple($keys, $default = null) |
||||
172 | { |
||||
173 | |||||
174 | } |
||||
175 | |||||
176 | |||||
177 | |||||
178 | /** |
||||
179 | * Persists a set of key => value pairs in the cache, with an optional TTL. |
||||
180 | * |
||||
181 | * @param iterable $values A list of key => value pairs for a |
||||
182 | * multiple-set operation. |
||||
183 | * @param null|int|\DateInterval $ttl Optional. The TTL value of this |
||||
184 | * item. If no value is sent and |
||||
185 | * the driver supports TTL then the |
||||
186 | * library may set a default value |
||||
187 | * for it or let the driver take care |
||||
188 | * of that. |
||||
189 | * |
||||
190 | * @return bool True on success and false on failure. |
||||
191 | * |
||||
192 | * @throws \Psr\SimpleCache\InvalidArgumentException |
||||
193 | * MUST be thrown if $values is neither an array nor a Traversable, |
||||
194 | * or if any of the $values are not a legal value. |
||||
195 | */ |
||||
196 | public function setMultiple($values, $ttl = null) |
||||
197 | { |
||||
198 | |||||
199 | } |
||||
200 | |||||
201 | |||||
202 | |||||
203 | /** |
||||
204 | * Deletes multiple cache items in a single operation. |
||||
205 | * |
||||
206 | * @param iterable $keys A list of string-based keys to be deleted. |
||||
207 | * |
||||
208 | * @return bool True if the items were successfully removed. False if there |
||||
209 | * was an error. |
||||
210 | * |
||||
211 | * @throws \Psr\SimpleCache\InvalidArgumentException |
||||
212 | * MUST be thrown if $keys is neither an array nor a Traversable, |
||||
213 | * or if any of the $keys are not a legal value. |
||||
214 | */ |
||||
215 | public function deleteMultiple($keys) |
||||
216 | { |
||||
217 | |||||
218 | } |
||||
219 | |||||
220 | |||||
221 | |||||
222 | /** |
||||
223 | * Determines whether an item is present in the cache. |
||||
224 | * |
||||
225 | * NOTE: It is recommended that has() is only to be used for cache warming |
||||
226 | * type purposes and not to be used within your live applications |
||||
227 | * operations for get/set, as this method is subject to a race condition |
||||
228 | * where your has() will return true and immediately after, another script |
||||
229 | * can remove it making the state of your app out of date. |
||||
230 | * |
||||
231 | * @param string $key The cache item key. |
||||
232 | * |
||||
233 | * @return bool |
||||
234 | * |
||||
235 | * @throws \Psr\SimpleCache\InvalidArgumentException |
||||
236 | * MUST be thrown if the $key string is not a legal value. |
||||
237 | */ |
||||
238 | public function has($key) |
||||
239 | { |
||||
240 | |||||
241 | } |
||||
242 | |||||
243 | |||||
244 | |||||
245 | /** |
||||
246 | * Create a key to use for the cache. |
||||
247 | * |
||||
248 | * @param string $class name of the class, including |
||||
249 | * namespace. |
||||
250 | * @param string $id unique id for item in each class. |
||||
251 | * |
||||
252 | * @return string the filename. |
||||
253 | */ |
||||
254 | public function createKey($class, $id) |
||||
255 | { |
||||
256 | return str_replace('\\', '-', $class) . '#' . $id; |
||||
257 | } |
||||
258 | |||||
259 | |||||
260 | |||||
261 | /** |
||||
262 | * Generate a filename for the cached object. |
||||
263 | * |
||||
264 | * @param string $key to the cached object. |
||||
265 | * |
||||
266 | * @return string the filename. |
||||
267 | */ |
||||
268 | private function filename($key) |
||||
269 | { |
||||
270 | return $this->cachePath . "/" . $key; |
||||
271 | } |
||||
272 | |||||
273 | |||||
274 | |||||
275 | // /** |
||||
276 | // * Get an item from the cache if available. |
||||
277 | // * |
||||
278 | // * @param string $key to the cached object. |
||||
279 | // * @param boolean $age check the age or not, defaults to |
||||
280 | // * false. |
||||
281 | // * |
||||
282 | // * @return mixed the cached object or false if it has aged |
||||
283 | // * or null if it does not exists. |
||||
284 | // */ |
||||
285 | // public function get($key, $age = false) |
||||
286 | // { |
||||
287 | // $file = $this->filename($key); |
||||
288 | // |
||||
289 | // if (is_file($file)) { |
||||
290 | // if ($age) { |
||||
291 | // $age = filemtime($file) + $this->config['age'] > time(); |
||||
292 | // } |
||||
293 | // |
||||
294 | // if (!$age) { |
||||
295 | // // json |
||||
296 | // // text |
||||
297 | // return unserialize(file_get_contents($file)); |
||||
298 | // } |
||||
299 | // return false; |
||||
300 | // } |
||||
301 | // return null; |
||||
302 | // } |
||||
303 | |||||
304 | |||||
305 | |||||
306 | // /** |
||||
307 | // * Put an item to the cache. |
||||
308 | // * |
||||
309 | // * @param string $key to the cached object. |
||||
310 | // * @param mixed $item the object to be cached. |
||||
311 | // * |
||||
312 | // * @throws Exception if failing to write to cache. |
||||
313 | // * |
||||
314 | // * @return void |
||||
315 | // */ |
||||
316 | // public function put($key, $item) |
||||
317 | // { |
||||
318 | // $file = $this->filename($key); |
||||
319 | // |
||||
320 | // // json |
||||
321 | // // text |
||||
322 | // if (!file_put_contents($file, serialize($item))) { |
||||
323 | // throw new \Exception( |
||||
324 | // t("Failed writing cache object '!key'.", [ |
||||
325 | // '!key' => $key |
||||
326 | // ]) |
||||
327 | // ); |
||||
328 | // } |
||||
329 | // } |
||||
330 | |||||
331 | |||||
332 | |||||
333 | // /** |
||||
334 | // * Prune a item from cache. |
||||
335 | // * |
||||
336 | // * @param string $key to the cached object. |
||||
337 | // * |
||||
338 | // * @return void |
||||
339 | // */ |
||||
340 | // public function prune($key) |
||||
341 | // { |
||||
342 | // @unlink($this->filename($key)); |
||||
343 | // } |
||||
344 | |||||
345 | |||||
346 | |||||
347 | // /** |
||||
348 | // * Prune all items from cache. |
||||
349 | // * |
||||
350 | // * @return int number of items removed. |
||||
351 | // */ |
||||
352 | // public function pruneAll() |
||||
353 | // { |
||||
354 | // $files = glob($this->config['basepath'] . '/*'); |
||||
355 | // $items = count($files); |
||||
356 | // array_map('unlink', $files); |
||||
357 | // return $items; |
||||
358 | // } |
||||
359 | } |
||||
360 |