Fakoli Framework
cache.inc
Go to the documentation of this file.
1 <?
2 /**************************************************************
3 
4  Copyright (c) 2007-2010 Sonjara, Inc
5 
6  Permission is hereby granted, free of charge, to any person
7  obtaining a copy of this software and associated documentation
8  files (the "Software"), to deal in the Software without
9  restriction, including without limitation the rights to use,
10  copy, modify, merge, publish, distribute, sublicense, and/or sell
11  copies of the Software, and to permit persons to whom the
12  Software is furnished to do so, subject to the following
13  conditions:
14 
15  The above copyright notice and this permission notice shall be
16  included in all copies or substantial portions of the Software.
17 
18  Except as contained in this notice, the name(s) of the above
19  copyright holders shall not be used in advertising or otherwise
20  to promote the sale, use or other dealings in this Software
21  without prior written authorization.
22 
23  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
25  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30  OTHER DEALINGS IN THE SOFTWARE.
31 
32 *****************************************************************/
33 
41 class Cache
42 {
43  static $instance;
44  static $app_name;
45 
46  static function getInstance()
47  {
48  global $config;
49 
50  trace(get_class(Cache::$instance), 5);
51 
53 
54  if (array_key_exists("file_backed_cache_directory", $config))
55  {
57  }
58  else if (ini_get("apc.enabled") && PHP_SAPI !== 'cli')
59  {
60  if (PHP_MAJOR_VERSION >= 7)
61  {
63  }
64  else
65  {
66  Cache::$instance = new APCCache();
67  }
68  }
69  else if (ini_get("wincache.ucenabled") && PHP_SAPI !== 'cli')
70  {
71  Cache::$instance = new WCCache();
72  }
73  else
74  {
76  }
77 
78  Cache::$app_name = codify($config['sitename']);
79 
80  return Cache::$instance;
81  }
82 
88  static function get($key)
89  {
91  }
92 
106  static function put($key, $obj, $ttl = 0)
107  {
108  return Cache::getInstance()->put(ConnectionManager::$dsn."_".Cache::$app_name."_".$key, $obj, $ttl);
109  }
110 
119  static function invalidate($key)
120  {
121  return Cache::getInstance()->invalidate(ConnectionManager::$dsn."_".Cache::$app_name."_".$key);
122  }
123 
133  static function invalidateMatching($pattern)
134  {
135  return Cache::getInstance()->invalidateMatching("^".ConnectionManager::$dsn."_".Cache::$app_name."_".$pattern);
136  }
137 
141  static function clear()
142  {
143  return Cache::getInstance()->clear();
144  }
145 
149  static function dump()
150  {
151  return Cache::getInstance()->dump();
152  }
153 }
154 
155 
163 {
164  var $cache;
165 
166  function SimpleMemoryCache()
167  {
168  trace("Creating Simple In-memory Cache", 4);
169  $this->cache = array();
170  }
171 
172  function get($key)
173  {
174  return $this->cache[$key];
175  }
176 
177  function put($key, $obj, $ttl = 0)
178  {
179  $this->cache[$key] = $obj;
180  return true;
181  // NOTE - ttl is ignored if using in-memory caching.
182  }
183 
184  function invalidate($key)
185  {
186  unset($this->cache[$key]);
187  return true;
188  }
189 
190  function invalidateMatching($pattern)
191  {
192  $this->pattern = $pattern;
193  $this->cache = arrayFilterKey($this->cache, array($this, filterKey));
194  unset($this->pattern);
195  }
196 
201  function filterKey($key)
202  {
203  return !preg_match("/".$this->pattern."/", $key);
204  }
205 
206  function clear()
207  {
208  $this->cache = array();
209  }
210 
211  function dump()
212  {
213  throw new FakoliException("Not implemented");
214  }
215 }
216 
217 
223 class APCCache
224 {
225  function APCCache()
226  {
227  trace("Creating APC Cache", 4);
228  }
229 
230  function get($key)
231  {
232  $success = true;
233 
234  $s = apc_fetch($key, $success);
235  if (!$success) return null;
236 
237  return unserialize($s);
238  }
239 
240  function put($key, $obj, $ttl = 0)
241  {
242  return apc_store($key, serialize($obj), $ttl);
243  }
244 
245  function invalidate($key)
246  {
247  return apc_delete($key);
248  }
249 
250  function invalidateMatching($pattern)
251  {
252  trace("invalidateMatching: $pattern", 3);
253  //TODO - Not working on zither - investigate
254  /*$iterator = new APCIterator("user", $pattern);
255 
256  while($key = $iterator->key())
257  {
258  trace($key, 3);
259  Cache::invalidate($key);
260  $iterator->next();
261  }*/
262  }
263 
264  function clear()
265  {
266  apc_clear_cache('user');
267  }
268 
269  function dump()
270  {
271  echo "<table class='list'><thead><tr><th>Key</th><th>Value</th></tr></thead><tbody>\n";
272 
273  $prefix = ConnectionManager::$dsn."_".Cache::$app_name."_";
274 
275  foreach (new APCIterator('user', '/.*/') as $kvp)
276  {
277  if (!startsWith($kvp['key'], $prefix)) continue;
278  $key = str_replace($prefix, "", $kvp['key']);
279  $value = htmlSafe($kvp['value']);
280 
281  echo "<tr><td><b>$key</b></td><td>{$value}</td></tr>\n";
282  }
283  echo "</tbody></table>";
284  }
285 }
286 
287 
288 
295 {
296  function __construct()
297  {
298  trace("Creating APCU Cache", 4);
299  }
300 
301  function get($key)
302  {
303  $success = true;
304 
305  $s = apcu_fetch($key, $success);
306  if (!$success) return null;
307 
308  return unserialize($s);
309  }
310 
311  function put($key, $obj, $ttl = 0)
312  {
313  return apcu_store($key, serialize($obj), $ttl);
314  }
315 
316  function invalidate($key)
317  {
318  return apcu_delete($key);
319  }
320 
321  function invalidateMatching($pattern)
322  {
323  trace("invalidateMatching: $pattern", 3);
324  //TODO - Not working on zither - investigate
325  /*$iterator = new APCUIterator("user", $pattern);
326 
327  while($key = $iterator->key())
328  {
329  trace($key, 3);
330  Cache::invalidate($key);
331  $iterator->next();
332  }*/
333  }
334 
335  function clear()
336  {
337  apcu_clear_cache('user');
338  }
339 
340  function dump()
341  {
342  echo "<table class='list'><thead><tr><th>Key</th><th>Value</th></tr></thead><tbody>\n";
343 
344  $prefix = ConnectionManager::$dsn."_".Cache::$app_name."_";
345 
346  foreach (new APCUIterator('/.*/') as $kvp)
347  {
348  if (!startsWith($kvp['key'], $prefix)) continue;
349  $key = str_replace($prefix, "", $kvp['key']);
350  $value = htmlSafe($kvp['value']);
351 
352  echo "<tr><td><b>$key</b></td><td>{$value}</td></tr>\n";
353  }
354  echo "</tbody></table>";
355  }
356 }
357 
361 class WCCache
362 {
363  function WCCache()
364  {
365  trace("Creating WinCache cache", 4);
366  }
367 
368  function get($key)
369  {
370  $value = wincache_ucache_get($key, $success);
371  if (!$success) return null;
372 
373  return unserialize($value);
374  }
375 
376  function put($key, $obj, $ttl = 0)
377  {
378  return wincache_ucache_set($key, serialize($obj), $ttl);
379  }
380 
381  function invalidate($key)
382  {
383  return wincache_ucache_delete($key);
384  }
385 
386  function invalidateMatching($pattern)
387  {
388  $this->pattern = $pattern;
389 
390  $info = wincache_ucache_info();
391 
392  $keys = array();
393 
394  foreach($info['ucache_entries'] as $entry)
395  {
396  $keys[] = $entry['key_name'];
397  }
398  $doomedKeys = array_filter($keys, array($this, filterKey));
399 
400  foreach($doomedKeys as $key)
401  {
402  $this->invalidate($key);
403  }
404 
405  unset($this->pattern);
406  }
407 
412  function filterKey($key)
413  {
414  return preg_match("/".$this->pattern."/", $key);
415  }
416 
417  function clear()
418  {
419  wincache_ucache_clear();
420  }
421 
422  function dump()
423  {
424  $info = wincache_ucache_info();
425  $prefix = ConnectionManager::$dsn."_".Cache::$app_name."_";
426  echo "<table class='list'><thead><tr><th>Key</th><th>Value</th></tr></thead><tbody>\n";
427  foreach ($info['ucache_entries'] as $kvp)
428  {
429  if (!startsWith($kvp['key_name'], $prefix)) continue;
430  $key = str_replace($prefix, "", $kvp['key_name']);
431 
432  echo "<tr><td><b>{$key}</b></td><td>".htmlSafe(wincache_ucache_get($kvp['key_name']))."</td></tr>\n";
433  }
434  echo "</tbody></table>";
435  }
436 }
437 
445 {
446  var $cache;
448 
449  function FileBackedCache()
450  {
451  global $config;
452 
453  trace("Creating File-backed Cache", 4);
454 
455  $this->cacheDir = $config["file_backed_cache_directory"];
456  $this->cache = array();
457 
458  trace("Cache Directory: {$this->cacheDir}", 3);
459  }
460 
461  function keyToFile($key)
462  {
463  return $this->cacheDir . DIRECTORY_SEPARATOR . $key . ".txt";
464  }
465 
466  function get($key)
467  {
468  if (array_key_exists($key, $this->cache)) return $this->cache[$key];
469  $file = $this->keyToFile($key);
470  if (file_exists($file))
471  {
472  $c = unserialize(file_get_contents($file));
473  $this->cache[$key] = $c;
474  return $c;
475  }
476  else return null;
477  }
478 
479  function put($key, $obj, $ttl = 0)
480  {
481  $this->cache[$key] = $obj;
482 
483  $file = $this->keyToFile($key);
484 
485  if (!file_exists($file))
486  {
487  $fp = fopen($file, "w");
488  fwrite($fp, serialize($obj));
489  fclose($fp);
490  }
491  else
492  {
493  $fp = fopen($file, "w+");
494 
495  if (flock($fp, LOCK_EX))
496  {
497  ftruncate($fp, 0);
498  fwrite($fp, serialize($obj));
499  flock($fp, LOCK_UN);
500  }
501  else
502  {
503  echo "Couldn't get the lock!";
504  }
505  }
506  fclose($fp);
507 
508  return true;
509  // NOTE - ttl is ignored if using in-memory caching.
510  }
511 
512  function invalidate($key)
513  {
514  $file = $this->keyToFile($key);
515 
516  if (file_exists($file)) unlink($file);
517  unset($this->cache[$key]);
518  return true;
519  }
520 
521  function invalidateMatching($pattern)
522  {
523  throw new FakoliException("FileBackedCache currently does not support the invalidateMatching() method");
524  }
525 
526  function clear()
527  {
528  foreach(glob($this->cacheDir . DIRECTORY_SEPARATOR . "*.txt") as $doomed)
529  {
530  unlink($doomed);
531  }
532  }
533 }
filterKey($key)
Internal callback function that supports the invalidateMatching function.
Definition: cache.inc:201
static invalidateMatching($pattern)
Invalidate all entries in the cache that match a specific pattern.
Definition: cache.inc:133
Provides a simple cacheing mechanism using the Alternative PHP Cache extension.
Definition: cache.inc:223
dump()
Definition: cache.inc:422
clear()
Definition: cache.inc:264
dump()
Definition: cache.inc:269
invalidate($key)
Definition: cache.inc:381
static $app_name
Definition: cache.inc:44
put($key, $obj, $ttl=0)
Definition: cache.inc:479
startsWith($text, $start)
Tests whether a string starts with a given sub-string.
Definition: functions.inc:1419
static clear()
Clear the cache, deleting all records.
Definition: cache.inc:141
put($key, $obj, $ttl=0)
Definition: cache.inc:311
clear()
Definition: cache.inc:417
Implements a simple in-memory cache when other cacheing mechanisms are not available.
Definition: cache.inc:162
static put($key, $obj, $ttl=0)
Store the specified object in the cache at the specified key.
Definition: cache.inc:106
invalidateMatching($pattern)
Definition: cache.inc:250
Provides a simple cacheing mechanism using the WinCache PHP extension (for use under IIS)...
Definition: cache.inc:361
invalidateMatching($pattern)
Definition: cache.inc:190
static getInstance()
Definition: cache.inc:46
Provides a simple File-backed caching implementation for when no shared memory caching extension is p...
Definition: cache.inc:444
invalidateMatching($pattern)
Definition: cache.inc:386
invalidate($key)
Definition: cache.inc:316
WCCache()
Definition: cache.inc:363
trace($msg, $lvl, $callStack=null)
Send output to the trace log.
Definition: functions.inc:959
APCCache()
Definition: cache.inc:225
put($key, $obj, $ttl=0)
Definition: cache.inc:240
dump()
Definition: cache.inc:340
static $instance
Definition: cache.inc:43
__construct()
Definition: cache.inc:296
keyToFile($key)
Definition: cache.inc:461
filterKey($key)
Internal callback function that supports the invalidateMatching function.
Definition: cache.inc:412
codify($name)
Takes a text string and converts it into a code-compliant format, suitable for use as a variable name...
Definition: functions.inc:1348
clear()
Definition: cache.inc:335
put($key, $obj, $ttl=0)
Definition: cache.inc:376
invalidateMatching($pattern)
Definition: cache.inc:321
static dump()
Output a dump of the cache for debugging purposes.
Definition: cache.inc:149
invalidateMatching($pattern)
Definition: cache.inc:521
put($key, $obj, $ttl=0)
Definition: cache.inc:177
arrayFilterKey( $input, $callback)
Filter an array based on applying the specified callback to the keys.
Definition: functions.inc:1692
static invalidate($key)
Invalidates the specifed entry in the cache.
Definition: cache.inc:119
Provides a simple cacheing mechanism using the Alternative PHP Cache extension.
Definition: cache.inc:294
The Cache class provides a simple caching interface.
Definition: cache.inc:41
invalidate($key)
Definition: cache.inc:245
invalidate($key)
Definition: cache.inc:184
invalidate($key)
Definition: cache.inc:512