source: trunk/lib/Cache.inc.php @ 162

Last change on this file since 162 was 162, checked in by scdev, 18 years ago

${1}

File size: 7.8 KB
RevLine 
[1]1<?php
2/**
[136]3 * Cache.inc.php
4 * code by strangecode :: www.strangecode.com :: this document contains copyrighted information
5 *
[1]6 * Provides an API for storing a limited amount of data
7 * intended to have a short lifetime in a user's session.
8 *
9 * @author  Quinn Comendant <quinn@strangecode.com>
[136]10 * @version 2.1
[1]11 * @since   2001
12 */
[136]13 
14// Flags.
[152]15define('CACHE_ALLOW_OVERSIZED', 1);
[136]16
17class Cache {
18
[152]19    // Namespace of this instance of Prefs.
20    var $_ns;
21
22    // Configuration parameters for this object.
[1]23    var $_params = array(
[152]24       
25        // If false nothing will be cached or retreived. Useful for testing realtime data requests.
[21]26        'enabled' => true,
[152]27
28        // The maximum size in bytes of any one variable.
29        'item_size_limit' => 4194304, // 4 MB
30       
31        // The maximum size in bytes before the cache will begin flushing out old items.
32        'stack_size_limit' => 4194304, // 4 MB
33       
34        // The minimum items to keep in the cache regardless of item or cache size.
35        'min_items' => 5,
[1]36    );
[152]37   
38    /*
39    * Constructor
40    *
41    * @access   public
42    * @param    string  $namespace  This object will store data under this realm.
43    * @author   Quinn Comendant <quinn@strangecode.com>
44    * @version  1.0
45    * @since    05 Jun 2006 23:14:21
46    */
47    function Cache($namespace='')
48    {
[154]49        $this->_ns = $namespace;
[152]50       
[154]51        if (!isset($_SESSION['_cache'][$this->_ns])) {
[152]52            $this->clear();
53        }
54    }
[1]55
56    /**
57     * This method enforces the singleton pattern for this class.
58     *
[136]59     * @return  object  Reference to the global Cache object.
[1]60     * @access  public
61     * @static
62     */
[152]63    function &getInstance($namespace='')
[136]64    {
[152]65        static $instances = array();
[1]66
[152]67        if (!array_key_exists($namespace, $instances)) {
68            $instances[$namespace] = new Cache($namespace);
[1]69        }
70
[152]71        return $instances[$namespace];
[1]72    }
73
74    /**
75     * Set (or overwrite existing) parameters by passing an array of new parameters.
76     *
77     * @access public
78     * @param  array    $params     Array of parameters (key => val pairs).
79     */
80    function setParam($params)
81    {
[136]82        $app =& App::getInstance();
[21]83
[1]84        if (isset($params) && is_array($params)) {
85            // Merge new parameters with old overriding only those passed.
[136]86            $this->_params = array_merge($this->_params, $params);
[1]87        } else {
[136]88            $app->logMsg(sprintf('Parameters are not an array: %s', $params), LOG_ERR, __FILE__, __LINE__);
[1]89        }
90    }
91
92    /**
93     * Return the value of a parameter, if it exists.
94     *
95     * @access public
96     * @param string $param        Which parameter to return.
97     * @return mixed               Configured parameter value.
98     */
99    function getParam($param)
100    {
[136]101        $app =& App::getInstance();
102   
103        if (isset($this->_params[$param])) {
104            return $this->_params[$param];
[1]105        } else {
[146]106            $app->logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
[1]107            return null;
108        }
109    }
110
111    /**
[136]112     * Stores a new variable in the session cache. The $key is is md5'ed
[152]113     * because if a key is numeric, the array_shift function
[136]114     * will reset the key to the next largest int key. Weird behavior I can't
[152]115     * understand. For example $cache["123"] will become $cache[0]
[1]116     *
[136]117     * @param str   $key        An identifier for the cached object.
[152]118     * @param mixed $var        The var to store in the session cache.
[136]119     * @param bool  $flags      If we have something really big that we
[152]120     *                          still want to cache, setting this to
121     *                          CACHE_ALLOW_OVERSIZED allows this.
122     * @return bool             True on success, false otherwise.
[1]123     */
[136]124    function set($key, $var, $flags=0)
[1]125    {
[136]126        $app =& App::getInstance();
[1]127
[152]128        if (true !== $this->getParam('enabled')) {
[136]129            $app->logMsg(sprintf('Cache not enabled, not saving data.', null), LOG_DEBUG, __FILE__, __LINE__);
[21]130            return false;
131        }
132
[153]133        $keyhash = md5($key);
[152]134        $var = serialize($var);
135        $var_len = strlen($var);
[42]136
[152]137        if ($var_len >= $this->getParam('item_size_limit')) {
138            $app->logMsg(sprintf('Serialized variable (%s bytes) more than item_size_limit (%s bytes).', $var_len, $this->getParam('item_size_limit')), LOG_NOTICE, __FILE__, __LINE__);
[1]139            return false;
140        }
[42]141
[152]142        if ($flags & CACHE_ALLOW_OVERSIZED == 0 && $var_len >= $this->getParam('stack_size_limit')) {
143            $app->logMsg(sprintf('Serialized variable (%s bytes) more than stack_size_limit (%s bytes).', $var_len, $this->getParam('stack_size_limit')), LOG_NOTICE, __FILE__, __LINE__);
[1]144            return false;
[152]145        }       
[1]146
[152]147        // Remove any value already stored under this key.
[154]148        unset($_SESSION['_cache'][$this->_ns][$keyhash]);
[152]149
150        // Continue to prune the cache if its size is greater than stack_size_limit, but keep at least min_items.
[154]151        while (strlen(serialize($_SESSION['_cache'][$this->_ns])) + $var_len >= $this->getParam('stack_size_limit') && sizeof($_SESSION['_cache'][$this->_ns]) >= $this->getParam('min_items')) {
152            array_shift($_SESSION['_cache'][$this->_ns]);
[1]153        }
[42]154
[152]155        // Save this value under the specified key.
[154]156        $_SESSION['_cache'][$this->_ns][$keyhash] =& $var;
[152]157
158        if ($var_len >= 1024000) {
159            $app->logMsg(sprintf('Successfully cached oversized variable (%s bytes).', $var_len), LOG_DEBUG, __FILE__, __LINE__);
[1]160        }
[42]161
[136]162        return true;
[1]163    }
[42]164
[1]165    /**
[42]166     * Retrives an object from the session cache and returns it unserialized.
[1]167     * It also moves it to the top of the stack, which makes it such that the
168     * cache flushing mechanism of putCache deletes the oldest referenced items
169     * first.
170     *
[136]171     * @param string $key  The key for the datum to retrieve.
[1]172     * @return mixed          The requested datum, or false on failure.
173     */
[136]174    function get($key)
[1]175    {
[153]176        $app =& App::getInstance();
[162]177
[152]178        if (true !== $this->getParam('enabled')) {
[153]179            $app->logMsg(sprintf('Cache not enabled, not getting data.', null), LOG_DEBUG, __FILE__, __LINE__);
[21]180            return false;
181        }
[42]182
[153]183        $keyhash = md5($key);
[154]184        if (isset($_SESSION['_cache'][$this->_ns][$keyhash])) {
[153]185            $app->logMsg(sprintf('Retreiving %s from cache.', $key), LOG_DEBUG, __FILE__, __LINE__);
[1]186            // Move the accessed cached datum to the top of the stack. Maybe somebody knows a better way to do this?
[154]187            $tmp =& $_SESSION['_cache'][$this->_ns][$keyhash];
188            unset($_SESSION['_cache'][$this->_ns][$keyhash]);
189            $_SESSION['_cache'][$this->_ns][$keyhash] =& $tmp;
[1]190            // Return the unserialized datum.
[154]191            return unserialize($_SESSION['_cache'][$this->_ns][$keyhash]);
[1]192        } else {
193            return false;
194        }
195    }
[42]196
[1]197    /**
198     * Tells you if the object is cached.
199     *
[136]200     * @param string $key  The key of the object to check.
[1]201     * @return bool           The return from isset().
202     */
[136]203    function exists($key)
[1]204    {
[152]205        if (true !== $this->getParam('enabled')) {
[21]206            return false;
207        }
208
[153]209        $keyhash = md5($key);
[154]210        return array_key_exists($keyhash, $_SESSION['_cache'][$this->_ns]);
[1]211    }
[42]212
[1]213    /**
214     * Tells you if the object is cached.
215     *
[136]216     * @param string $key  The key of the object to check.
[1]217     * @return bool           The return from isset().
218     */
[136]219    function delete($key)
[1]220    {
[153]221        $keyhash = md5($key);
[154]222        unset($_SESSION['_cache'][$this->_ns][$keyhash]);
[1]223    }
[152]224   
225    /*
226    * Delete all existing items from the cache.
227    *
228    * @access   public
229    * @author   Quinn Comendant <quinn@strangecode.com>
230    * @version  1.0
231    * @since    05 Jun 2006 23:51:34
232    */
233    function clear()
234    {
[154]235        $_SESSION['_cache'][$this->_ns] = array();
[152]236    }
[1]237
[136]238// END Cache
[1]239}
240
241?>
Note: See TracBrowser for help on using the repository browser.