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

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

Q - added persistant database storage to Prefs.inc.php. Modified getParam failure log type to LOG_DEBUG in all classes.

File size: 6.6 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.
15define('CACHE_IGNORE_SIZE', 1);
16
17class Cache {
18
[1]19    var $_params = array(
[21]20        'enabled' => true,
[1]21        'soft_limit' => 204800,
22        'hard_limit' => 4194304,
23        'min_items' => 3,
24    );
25
26    /**
27     * This method enforces the singleton pattern for this class.
28     *
[136]29     * @return  object  Reference to the global Cache object.
[1]30     * @access  public
31     * @static
32     */
[136]33    function &getInstance()
34    {
[1]35        static $instance = null;
36
37        if ($instance === null) {
[136]38            $instance = new Cache();
[1]39        }
40
41        return $instance;
42    }
43
44    /**
45     * Set (or overwrite existing) parameters by passing an array of new parameters.
46     *
47     * @access public
48     * @param  array    $params     Array of parameters (key => val pairs).
49     */
50    function setParam($params)
51    {
[136]52        $app =& App::getInstance();
[21]53
[1]54        if (isset($params) && is_array($params)) {
55            // Merge new parameters with old overriding only those passed.
[136]56            $this->_params = array_merge($this->_params, $params);
[1]57        } else {
[136]58            $app->logMsg(sprintf('Parameters are not an array: %s', $params), LOG_ERR, __FILE__, __LINE__);
[1]59        }
60    }
61
62    /**
63     * Return the value of a parameter, if it exists.
64     *
65     * @access public
66     * @param string $param        Which parameter to return.
67     * @return mixed               Configured parameter value.
68     */
69    function getParam($param)
70    {
[136]71        $app =& App::getInstance();
72   
73        if (isset($this->_params[$param])) {
74            return $this->_params[$param];
[1]75        } else {
[146]76            $app->logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
[1]77            return null;
78        }
79    }
80
81    /**
[136]82     * Stores a new variable in the session cache. The $key is is md5'ed
[1]83     * because if a variable id is a very large integer, the array_shift function
[136]84     * will reset the key to the next largest int key. Weird behavior I can't
[1]85     * understand. $session_cache[32341234123] will become $session_cache[0]
86     * for example. Usage warning: if the variable is too big to fit, or is
87     * old and discarded, you must provide alternative ways of accessing the data.
88     *
[136]89     * @param str   $key        An identifier for the cached object.
[1]90     * @param mixed $var          The var to store in the session cache.
[136]91     * @param bool  $flags      If we have something really big that we
92     *                            still want to cache, setting this to
93     *                            CACHE_IGNORE_SIZE allows this.
[1]94     *
[136]95     * @return bool               True on success, false otherwise.
[1]96     */
[136]97    function set($key, $var, $flags=0)
[1]98    {
[136]99        $app =& App::getInstance();
[1]100
[136]101        if (!$this->getParam('enabled')) {
102            $app->logMsg(sprintf('Cache not enabled, not saving data.', null), LOG_DEBUG, __FILE__, __LINE__);
[21]103            return false;
104        }
105
[136]106        $key = md5($key);
[1]107        $serialized_var = serialize($var);
108        $serialized_var_len = strlen($serialized_var);
[42]109
[136]110        if ($flags & CACHE_IGNORE_SIZE > 0 && $serialized_var_len >= $this->getParam('soft_limit')) {
111            $app->logMsg(sprintf('Serialized variable (%s bytes) more than soft_limit (%s bytes).', $serialized_var_len, $this->getParam('soft_limit')), LOG_NOTICE, __FILE__, __LINE__);
[1]112            return false;
113        }
[42]114
[136]115        if ($serialized_var_len >= $this->getParam('hard_limit')) {
116            $app->logMsg(sprintf('Serialized variable (%s bytes) more than hard_limit (%s bytes).', $serialized_var_len, $this->getParam('hard_limit')), LOG_NOTICE, __FILE__, __LINE__);
[1]117            return false;
118        }
119
120        if (!isset($_SESSION['_session_cache'])) {
121            $_SESSION['_session_cache'] = array();
122        } else {
[136]123            unset($_SESSION['_session_cache'][$key]);
[1]124            // Continue to prune the cache if it's length is too long for the new variable to fit, but keep at least MIN_ITEMS at least.
[136]125            while (strlen(serialize($_SESSION['_session_cache'])) + $serialized_var_len >= $this->getParam('soft_limit')
126            && sizeof($_SESSION['_session_cache']) >= $this->getParam('min_items')) {
[1]127                array_shift($_SESSION['_session_cache']);
128            }
129        }
[136]130        $_SESSION['_session_cache'][$key] =& $serialized_var;
[42]131
[1]132        if ($serialized_var_len >= 1024000) {
[136]133            $app->logMsg(sprintf('Successfully cached oversized variable (%s bytes).', $serialized_var_len), LOG_DEBUG, __FILE__, __LINE__);
[1]134        }
[42]135
[136]136        return true;
[1]137    }
[42]138
[1]139    /**
[42]140     * Retrives an object from the session cache and returns it unserialized.
[1]141     * It also moves it to the top of the stack, which makes it such that the
142     * cache flushing mechanism of putCache deletes the oldest referenced items
143     * first.
144     *
[136]145     * @param string $key  The key for the datum to retrieve.
[1]146     *
147     * @return mixed          The requested datum, or false on failure.
148     */
[136]149    function get($key)
[1]150    {
[136]151        if (!$this->getParam('enabled')) {
[21]152            return false;
153        }
[42]154
[136]155        $key = md5($key);
156        if (isset($_SESSION['_session_cache'][$key])) {
[1]157            // Move the accessed cached datum to the top of the stack. Maybe somebody knows a better way to do this?
[136]158            $tmp =& $_SESSION['_session_cache'][$key];
159            unset($_SESSION['_session_cache'][$key]);
160            $_SESSION['_session_cache'][$key] =& $tmp;
[1]161            // Return the unserialized datum.
[136]162            return unserialize($_SESSION['_session_cache'][$key]);
[1]163        } else {
164            return false;
165        }
166    }
[42]167
[1]168    /**
169     * Tells you if the object is cached.
170     *
[136]171     * @param string $key  The key of the object to check.
[1]172     *
173     * @return bool           The return from isset().
174     */
[136]175    function exists($key)
[1]176    {
[136]177        if (!$this->getParam('enabled')) {
[21]178            return false;
179        }
180
[136]181        $key = md5($key);
182        return isset($_SESSION['_session_cache'][$key]);
[1]183    }
[42]184
[1]185    /**
186     * Tells you if the object is cached.
187     *
[136]188     * @param string $key  The key of the object to check.
[1]189     *
190     * @return bool           The return from isset().
191     */
[136]192    function delete($key)
[1]193    {
[136]194        $key = md5($key);
195        if (isset($_SESSION['_session_cache'][$key])) {
196            unset($_SESSION['_session_cache'][$key]);
[1]197        }
198    }
199
[136]200// END Cache
[1]201}
202
203?>
Note: See TracBrowser for help on using the repository browser.