source: branches/eli_branch/lib/Cache.inc.php @ 443

Last change on this file since 443 was 439, checked in by anonymous, 11 years ago

added public and private keywords to all properties and methods, changed old classname constructor function to construct, removed more ?> closing tags

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