source: tags/2.1.5/lib/Cache.inc.php

Last change on this file was 377, checked in by quinn, 14 years ago

Releasing trunk as stable version 2.1.5

File size: 9.0 KB
RevLine 
[1]1<?php
2/**
[362]3 * The Strangecode Codebase - a general application development framework for PHP
4 * For details visit the project site: <http://trac.strangecode.com/codebase/>
[376]5 * Copyright 2001-2010 Strangecode, LLC
[362]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/**
[136]24 * Cache.inc.php
25 *
[1]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>
[136]30 * @version 2.1
[1]31 * @since   2001
32 */
[136]33 
34// Flags.
[152]35define('CACHE_ALLOW_OVERSIZED', 1);
[136]36
37class Cache {
38
[152]39    // Namespace of this instance of Prefs.
40    var $_ns;
41
42    // Configuration parameters for this object.
[1]43    var $_params = array(
[152]44       
[334]45        // If false nothing will be cached or retrieved. Useful for testing realtime data requests.
[21]46        'enabled' => true,
[152]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,
[1]56    );
[152]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 Cache($namespace='')
68    {
[172]69        $app =& App::getInstance();
70       
[154]71        $this->_ns = $namespace;
[172]72
73        if (true !== $app->getParam('enable_session')) {
[238]74            $app->logMsg('Cache disabled, enable_session is false.', LOG_DEBUG, __FILE__, __LINE__);
[172]75            $this->setParam(array('enabled' => false));
76        }
[152]77       
[154]78        if (!isset($_SESSION['_cache'][$this->_ns])) {
[152]79            $this->clear();
80        }
81    }
[1]82
83    /**
84     * This method enforces the singleton pattern for this class.
85     *
[136]86     * @return  object  Reference to the global Cache object.
[1]87     * @access  public
88     * @static
89     */
[152]90    function &getInstance($namespace='')
[136]91    {
[152]92        static $instances = array();
[1]93
[152]94        if (!array_key_exists($namespace, $instances)) {
95            $instances[$namespace] = new Cache($namespace);
[1]96        }
97
[152]98        return $instances[$namespace];
[1]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    function setParam($params)
108    {
[136]109        $app =& App::getInstance();
[21]110
[1]111        if (isset($params) && is_array($params)) {
112            // Merge new parameters with old overriding only those passed.
[136]113            $this->_params = array_merge($this->_params, $params);
[1]114        } else {
[136]115            $app->logMsg(sprintf('Parameters are not an array: %s', $params), LOG_ERR, __FILE__, __LINE__);
[1]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    function getParam($param)
127    {
[136]128        $app =& App::getInstance();
129   
130        if (isset($this->_params[$param])) {
131            return $this->_params[$param];
[1]132        } else {
[146]133            $app->logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
[1]134            return null;
135        }
136    }
137
138    /**
[334]139     * Stores a new variable in the session cache. The $key should not be numeric
[174]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]
[1]142     *
[136]143     * @param str   $key        An identifier for the cached object.
[152]144     * @param mixed $var        The var to store in the session cache.
[136]145     * @param bool  $flags      If we have something really big that we
[152]146     *                          still want to cache, setting this to
147     *                          CACHE_ALLOW_OVERSIZED allows this.
148     * @return bool             True on success, false otherwise.
[1]149     */
[136]150    function set($key, $var, $flags=0)
[1]151    {
[136]152        $app =& App::getInstance();
[1]153
[152]154        if (true !== $this->getParam('enabled')) {
[316]155            $app->logMsg(sprintf('Cache disabled, not saving data.', null), LOG_DEBUG, __FILE__, __LINE__);
[21]156            return false;
157        }
158
[152]159        $var = serialize($var);
[247]160        $var_len = mb_strlen($var);
[42]161
[152]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__);
[1]164            return false;
165        }
[42]166
[152]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__);
[1]169            return false;
[152]170        }       
[1]171
[152]172        // Remove any value already stored under this key.
[174]173        unset($_SESSION['_cache'][$this->_ns][$key]);
[152]174
175        // Continue to prune the cache if its size is greater than stack_size_limit, but keep at least min_items.
[247]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')) {
[154]177            array_shift($_SESSION['_cache'][$this->_ns]);
[1]178        }
[42]179
[152]180        // Save this value under the specified key.
[174]181        $_SESSION['_cache'][$this->_ns][$key] =& $var;
[152]182
183        if ($var_len >= 1024000) {
184            $app->logMsg(sprintf('Successfully cached oversized variable (%s bytes).', $var_len), LOG_DEBUG, __FILE__, __LINE__);
[1]185        }
[42]186
[136]187        return true;
[1]188    }
[42]189
[1]190    /**
[334]191     * Retrieves an object from the session cache and returns it unserialized.
[1]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     *
[136]196     * @param string $key  The key for the datum to retrieve.
[1]197     * @return mixed          The requested datum, or false on failure.
198     */
[136]199    function get($key)
[1]200    {
[153]201        $app =& App::getInstance();
[162]202
[152]203        if (true !== $this->getParam('enabled')) {
[316]204            $app->logMsg(sprintf('Cache disabled, not getting data.', null), LOG_DEBUG, __FILE__, __LINE__);
[21]205            return false;
206        }
[42]207
[218]208        if (array_key_exists($key, $_SESSION['_cache'][$this->_ns])) {
[153]209            $app->logMsg(sprintf('Retreiving %s from cache.', $key), LOG_DEBUG, __FILE__, __LINE__);
[1]210            // Move the accessed cached datum to the top of the stack. Maybe somebody knows a better way to do this?
[174]211            $tmp =& $_SESSION['_cache'][$this->_ns][$key];
212            unset($_SESSION['_cache'][$this->_ns][$key]);
213            $_SESSION['_cache'][$this->_ns][$key] =& $tmp;
[1]214            // Return the unserialized datum.
[174]215            return unserialize($_SESSION['_cache'][$this->_ns][$key]);
[1]216        } else {
[172]217            $app->logMsg(sprintf('Missing %s from cache.', $key), LOG_DEBUG, __FILE__, __LINE__);
[1]218            return false;
219        }
220    }
[42]221
[1]222    /**
223     * Tells you if the object is cached.
224     *
[136]225     * @param string $key  The key of the object to check.
[218]226     * @return bool         True if a value exists for the given key.
[1]227     */
[136]228    function exists($key)
[1]229    {
[152]230        if (true !== $this->getParam('enabled')) {
[21]231            return false;
232        }
233
[174]234        return array_key_exists($key, $_SESSION['_cache'][$this->_ns]);
[1]235    }
[42]236
[1]237    /**
[188]238     * Removes a cached object.
[1]239     *
[136]240     * @param string $key  The key of the object to check.
[218]241     * @return bool         True if the value existed before being unset.
[1]242     */
[136]243    function delete($key)
[1]244    {
[218]245        if (array_key_exists($key, $_SESSION['_cache'][$this->_ns])) {
246            unset($_SESSION['_cache'][$this->_ns][$key]);
247            return true;
248        } else {
249            return false;
250        }
[1]251    }
[152]252   
253    /*
254    * Delete all existing items from the cache.
255    *
256    * @access   public
257    * @author   Quinn Comendant <quinn@strangecode.com>
258    * @version  1.0
259    * @since    05 Jun 2006 23:51:34
260    */
261    function clear()
262    {
[154]263        $_SESSION['_cache'][$this->_ns] = array();
[152]264    }
[1]265
[136]266// END Cache
[1]267}
268
269?>
Note: See TracBrowser for help on using the repository browser.