2
// +----------------------------------------------------------------------+
4
// +----------------------------------------------------------------------+
5
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 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
// +----------------------------------------------------------------------+
19
// $Id: Cache.php 6184 2008-08-22 10:33:41Z vargenau $
21
require_once('PEAR.php');
22
require_once('Cache/Error.php');
25
* Cache is a base class for cache implementations.
27
* The pear cache module is a generic data cache which can be used to
28
* cache script runs. The idea behind the cache is quite simple. If you have
29
* the same input parameters for whatever tasks/algorithm you use you'll
30
* usually get the same output. So why not caching templates, functions calls,
31
* graphic generation etc. Caching certain actions e.g. XSLT tranformations
32
* saves you lots of time.
34
* The design of the cache reminds of PHPLibs session implementation. A
35
* (PHPLib: session) controller uses storage container (PHPLib: ct_*.inc) to save
36
* certain data (PHPLib: session data). In contrast to the session stuff it's up to
37
* you to generate an ID for the data to cache. If you're using the output cache
38
* you might use the script name as a seed for cache::generateID(), if your using the
39
* function cache you'd use an array with all function parameters.
41
* Usage example of the generic data cache:
43
* require_once('Cache.php');
45
* $cache = new Cache('file', array('cache_dir' => 'cache/') );
46
* $id = $cache->generateID('testentry');
48
* if ($data = $cache->get($id)) {
49
* print "Cache hit.<br>Data: $data";
52
* $data = 'data of any kind';
53
* $cache->save($id, $data);
54
* print 'Cache miss.<br>';
57
* WARNING: No File/DB-Table-Row locking is implemented yet,
58
* it's possible, that you get corrupted data-entries under
59
* bad circumstances (especially with the file container)
61
* @author Ulf Wendel <ulf.wendel@phpdoc.de>
62
* @version $Id: Cache.php 6184 2008-08-22 10:33:41Z vargenau $
66
class Cache extends PEAR {
69
* Enables / disables caching.
71
* TODO: Add explanation what this is good for.
79
* Garbage collection: probability in seconds
81
* If set to a value above 0 a garbage collection will
82
* flush all cache entries older than the specified number
86
* @see $gc_probability, $gc_maxlifetime
92
* Garbage collection: probability in percent
94
* TODO: Add an explanation.
96
* @var integer 0 => never
97
* @see $gc_time, $gc_maxlifetime
100
var $gc_probability = 1;
103
* Garbage collection: delete all entries not use for n seconds.
105
* Default is one day, 60 * 60 * 24 = 86400 seconds.
108
* @see $gc_probability, $gc_time
110
var $gc_maxlifetime = 86400;
113
* Storage container object.
115
* @var object Cache_Container
125
* @param string Name of container class
126
* @param array Array with container class options
128
function Cache($container, $container_options = '')
131
$container = strtolower($container);
132
$container_class = 'Cache_Container_' . $container;
133
$container_classfile = 'Cache/Container/' . $container . '.php';
135
include_once $container_classfile;
136
$this->container = new $container_class($container_options);
142
$this->garbageCollection();
146
* Returns the current caching state.
148
* @return boolean The current caching state.
151
function getCaching()
153
return ($this->caching);
157
* Enables or disables caching.
159
* @param boolean The new caching state.
162
function setCaching($state)
164
$this->caching = $state;
168
* Returns the requested dataset it if exists and is not expired
170
* @param string dataset ID
171
* @param string cache group
172
* @return mixed cached data or NULL on failure
175
function get($id, $group = 'default') {
179
if ($this->isCached($id, $group) && !$this->isExpired($id, $group))
180
return $this->load($id, $group);
186
* Stores the given data in the cache.
188
* @param string dataset ID used as cache identifier
189
* @param mixed data to cache
190
* @param integer lifetime of the cached data in seconds - 0 for endless
191
* @param string cache group
195
function save($id, $data, $expires = 0, $group = 'default') {
199
return $this->extSave($id, $data, '',$expires, $group);
203
* Stores a dataset without additional userdefined data.
205
* @param string dataset ID
206
* @param mixed data to store
207
* @param string additional userdefined data
208
* @param mixed userdefined expire date
209
* @param string cache group
211
* @throws Cache_Error
215
function extSave($id, $cachedata, $userdata, $expires = 0, $group = 'default') {
219
return $this->container->save($id, $cachedata, $expires, $group, $userdata);
220
} // end func extSave
223
* Loads the given ID from the cache.
225
* @param string dataset ID
226
* @param string cache group
227
* @return mixed cached data or NULL on failure
230
function load($id, $group = 'default') {
234
return $this->container->load($id, $group);
238
* Returns the userdata field of a cached data set.
240
* @param string dataset ID
241
* @param string cache group
242
* @return string userdata
246
function getUserdata($id, $group = 'default') {
250
return $this->container->getUserdata($id, $group);
251
} // end func getUserdata
254
* Removes the specified dataset from the cache.
256
* @param string dataset ID
257
* @param string cache group
261
function remove($id, $group = 'default') {
265
return $this->container->remove($id, $group);
269
* Flushes the cache - removes all data from it
271
* @param string cache group, if empty all groups will be flashed
272
* @return integer number of removed datasets
274
function flush($group = 'default') {
278
return $this->container->flush($group);
282
* Checks if a dataset exists.
284
* Note: this does not say that the cached data is not expired!
286
* @param string dataset ID
287
* @param string cache group
291
function isCached($id, $group = 'default') {
295
return $this->container->isCached($id, $group);
296
} // end func isCached
299
* Checks if a dataset is expired
301
* @param string dataset ID
302
* @param string cache group
303
* @param integer maximum age for the cached data in seconds - 0 for endless
304
* If the cached data is older but the given lifetime it will
305
* be removed from the cache. You don't have to provide this
306
* argument if you call isExpired(). Every dataset knows
307
* it's expire date and will be removed automatically. Use
308
* this only if you know what you're doing...
312
function isExpired($id, $group = 'default', $max_age = 0) {
316
return $this->container->isExpired($id, $group, $max_age);
317
} // end func isExpired
320
* Generates a "unique" ID for the given value
322
* This is a quick but dirty hack to get a "unique" ID for a any kind of variable.
323
* ID clashes might occur from time to time although they are extreme unlikely!
325
* @param mixed variable to generate a ID for
326
* @return string "unique" ID
329
function generateID($variable) {
330
// WARNING: ID clashes are possible although unlikely
331
return md5(serialize($variable));
335
* Calls the garbage collector of the storage object with a certain probability
337
* @param boolean Force a garbage collection run?
338
* @see $gc_probability, $gc_time
340
function garbageCollection($force = false) {
341
static $last_run = 0;
346
srand((double) microtime() * 1000000);
348
// time and probability based
349
if (($force) || ($last_run && $last_run < time() + $this->gc_time) || (rand(1, 100) < $this->gc_probability)) {
350
$this->container->garbageCollection($this->gc_maxlifetime);
353
} // end func garbageCollection