PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/inc/Cache.php

https://github.com/chregu/fluxcms
PHP | 356 lines | 92 code | 38 blank | 226 comment | 16 complexity | 3db1a1056d39c662a337f60b6343b70b MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PEAR :: Cache |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1997-2003 The PHP Group |
  6. // +----------------------------------------------------------------------+
  7. // | This source file is subject to version 2.0 of the PHP license, |
  8. // | that is bundled with this package in the file LICENSE, and is |
  9. // | available at through the world-wide-web at |
  10. // | http://www.php.net/license/2_02.txt. |
  11. // | If you did not receive a copy of the PHP license and are unable to |
  12. // | obtain it through the world-wide-web, please send a note to |
  13. // | license@php.net so we can mail you a copy immediately. |
  14. // +----------------------------------------------------------------------+
  15. // | Authors: Ulf Wendel <ulf.wendel@phpdoc.de> |
  16. // | Sebastian Bergmann <sb@sebastian-bergmann.de> |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id$
  20. require_once 'PEAR.php';
  21. require_once 'Cache/Error.php';
  22. /**
  23. * Cache is a base class for cache implementations.
  24. *
  25. * The pear cache module is a generic data cache which can be used to
  26. * cache script runs. The idea behind the cache is quite simple. If you have
  27. * the same input parameters for whatever tasks/algorithm you use you'll
  28. * usually get the same output. So why not caching templates, functions calls,
  29. * graphic generation etc. Caching certain actions e.g. XSLT tranformations
  30. * saves you lots of time.
  31. *
  32. * The design of the cache reminds of PHPLibs session implementation. A
  33. * (PHPLib: session) controller uses storage container (PHPLib: ct_*.inc) to save
  34. * certain data (PHPLib: session data). In contrast to the session stuff it's up to
  35. * you to generate an ID for the data to cache. If you're using the output cache
  36. * you might use the script name as a seed for cache::generateID(), if your using the
  37. * function cache you'd use an array with all function parameters.
  38. *
  39. * Usage example of the generic data cache:
  40. *
  41. * require_once('Cache.php');
  42. *
  43. * $cache = new Cache('file', array('cache_dir' => 'cache/') );
  44. * $id = $cache->generateID('testentry');
  45. *
  46. * if ($data = $cache->get($id)) {
  47. * print "Cache hit.<br>Data: $data";
  48. *
  49. * } else {
  50. * $data = 'data of any kind';
  51. * $cache->save($id, $data);
  52. * print 'Cache miss.<br>';
  53. * }
  54. *
  55. * WARNING: No File/DB-Table-Row locking is implemented yet,
  56. * it's possible, that you get corrupted data-entries under
  57. * bad circumstances (especially with the file container)
  58. *
  59. * @author Ulf Wendel <ulf.wendel@phpdoc.de>
  60. * @version $Id$
  61. * @package Cache
  62. * @access public
  63. */
  64. class Cache extends PEAR {
  65. /**
  66. * Enables / disables caching.
  67. *
  68. * TODO: Add explanation what this is good for.
  69. *
  70. * @var boolean
  71. * @access private
  72. */
  73. var $caching = true;
  74. /**
  75. * Garbage collection: probability in seconds
  76. *
  77. * If set to a value above 0 a garbage collection will
  78. * flush all cache entries older than the specified number
  79. * of seconds.
  80. *
  81. * @var integer
  82. * @see $gc_probability, $gc_maxlifetime
  83. * @access public
  84. */
  85. var $gc_time = 1;
  86. /**
  87. * Garbage collection: probability in percent
  88. *
  89. * TODO: Add an explanation.
  90. *
  91. * @var integer 0 => never
  92. * @see $gc_time, $gc_maxlifetime
  93. * @access public
  94. */
  95. var $gc_probability = 1;
  96. /**
  97. * Garbage collection: delete all entries not use for n seconds.
  98. *
  99. * Default is one day, 60 * 60 * 24 = 86400 seconds.
  100. *
  101. * @var integer
  102. * @see $gc_probability, $gc_time
  103. */
  104. var $gc_maxlifetime = 86400;
  105. /**
  106. * Storage container object.
  107. *
  108. * @var object Cache_Container
  109. */
  110. var $container;
  111. //
  112. // public methods
  113. //
  114. /**
  115. *
  116. * @param string Name of container class
  117. * @param array Array with container class options
  118. */
  119. function Cache($container, $container_options = '')
  120. {
  121. $this->PEAR();
  122. $container = strtolower($container);
  123. $container_class = 'Cache_Container_' . $container;
  124. $container_classfile = 'Cache/Container/' . $container . '.php';
  125. include_once $container_classfile;
  126. $this->container = new $container_class($container_options);
  127. }
  128. //deconstructor
  129. function _Cache()
  130. {
  131. $this->garbageCollection();
  132. }
  133. /**
  134. * Returns the current caching state.
  135. *
  136. * @return boolean The current caching state.
  137. * @access public
  138. */
  139. function getCaching()
  140. {
  141. return ($this->caching);
  142. }
  143. /**
  144. * Enables or disables caching.
  145. *
  146. * @param boolean The new caching state.
  147. * @access public
  148. */
  149. function setCaching($state)
  150. {
  151. $this->caching = $state;
  152. }
  153. /**
  154. * Returns the requested dataset it if exists and is not expired
  155. *
  156. * @param string dataset ID
  157. * @param string cache group
  158. * @return mixed cached data or NULL on failure
  159. * @access public
  160. */
  161. function get($id, $group = 'default') {
  162. if (!$this->caching)
  163. return '';
  164. if ($this->isCached($id, $group) && !$this->isExpired($id, $group))
  165. return $this->load($id, $group);
  166. return NULL;
  167. } // end func get
  168. /**
  169. * Stores the given data in the cache.
  170. *
  171. * @param string dataset ID used as cache identifier
  172. * @param mixed data to cache
  173. * @param integer lifetime of the cached data in seconds - 0 for endless
  174. * @param string cache group
  175. * @return boolean
  176. * @access public
  177. */
  178. function save($id, $data, $expires = 0, $group = 'default') {
  179. if (!$this->caching)
  180. return true;
  181. return $this->extSave($id, $data, '',$expires, $group);
  182. } // end func save
  183. /**
  184. * Stores a dataset with additional userdefined data.
  185. *
  186. * @param string dataset ID
  187. * @param mixed data to store
  188. * @param string additional userdefined data
  189. * @param mixed userdefined expire date
  190. * @param string cache group
  191. * @return boolean
  192. * @throws Cache_Error
  193. * @access public
  194. * @see getUserdata()
  195. */
  196. function extSave($id, $cachedata, $userdata, $expires = 0, $group = 'default') {
  197. if (!$this->caching)
  198. return true;
  199. return $this->container->save($id, $cachedata, $expires, $group, $userdata);
  200. } // end func extSave
  201. /**
  202. * Loads the given ID from the cache.
  203. *
  204. * @param string dataset ID
  205. * @param string cache group
  206. * @return mixed cached data or NULL on failure
  207. * @access public
  208. */
  209. function load($id, $group = 'default') {
  210. if (!$this->caching)
  211. return '';
  212. return $this->container->load($id, $group);
  213. } // end func load
  214. /**
  215. * Returns the userdata field of a cached data set.
  216. *
  217. * @param string dataset ID
  218. * @param string cache group
  219. * @return string userdata
  220. * @access public
  221. * @see extSave()
  222. */
  223. function getUserdata($id, $group = 'default') {
  224. if (!$this->caching)
  225. return '';
  226. return $this->container->getUserdata($id, $group);
  227. } // end func getUserdata
  228. /**
  229. * Removes the specified dataset from the cache.
  230. *
  231. * @param string dataset ID
  232. * @param string cache group
  233. * @return boolean
  234. * @access public
  235. */
  236. function remove($id, $group = 'default') {
  237. if (!$this->caching)
  238. return true;
  239. return $this->container->remove($id, $group);
  240. } // end func remove
  241. /**
  242. * Flushes the cache - removes all data from it
  243. *
  244. * @param string cache group, if empty all groups will be flashed
  245. * @return integer number of removed datasets
  246. */
  247. function flush($group = 'default') {
  248. if (!$this->caching)
  249. return true;
  250. return $this->container->flush($group);
  251. } // end func flush
  252. /**
  253. * Checks if a dataset exists.
  254. *
  255. * Note: this does not say that the cached data is not expired!
  256. *
  257. * @param string dataset ID
  258. * @param string cache group
  259. * @return boolean
  260. * @access public
  261. */
  262. function isCached($id, $group = 'default') {
  263. if (!$this->caching)
  264. return false;
  265. return $this->container->isCached($id, $group);
  266. } // end func isCached
  267. /**
  268. * Checks if a dataset is expired
  269. *
  270. * @param string dataset ID
  271. * @param string cache group
  272. * @param integer maximum age for the cached data in seconds - 0 for endless
  273. * If the cached data is older but the given lifetime it will
  274. * be removed from the cache. You don't have to provide this
  275. * argument if you call isExpired(). Every dataset knows
  276. * it's expire date and will be removed automatically. Use
  277. * this only if you know what you're doing...
  278. * @return boolean
  279. * @access public
  280. */
  281. function isExpired($id, $group = 'default', $max_age = 0) {
  282. if (!$this->caching)
  283. return true;
  284. return $this->container->isExpired($id, $group, $max_age);
  285. } // end func isExpired
  286. /**
  287. * Generates a "unique" ID for the given value
  288. *
  289. * This is a quick but dirty hack to get a "unique" ID for a any kind of variable.
  290. * ID clashes might occur from time to time although they are extreme unlikely!
  291. *
  292. * @param mixed variable to generate a ID for
  293. * @return string "unique" ID
  294. * @access public
  295. */
  296. function generateID($variable) {
  297. // WARNING: ID clashes are possible although unlikely
  298. return md5(serialize($variable));
  299. }
  300. /**
  301. * Calls the garbage collector of the storage object with a certain probability
  302. *
  303. * @param boolean Force a garbage collection run?
  304. * @see $gc_probability, $gc_time
  305. */
  306. function garbageCollection($force = false) {
  307. static $last_run = 0;
  308. if (!$this->caching)
  309. return;
  310. srand((double) microtime() * 1000000);
  311. // time and probability based
  312. if (($force) || ($last_run && $last_run < time() + $this->gc_time) || (rand(1, 100) < $this->gc_probability)) {
  313. $this->container->garbageCollection($this->gc_maxlifetime);
  314. $last_run = time();
  315. }
  316. } // end func garbageCollection
  317. } // end class cache
  318. ?>