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

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

Q - added move method to ACL class, added polish.

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