├── README.markdown ├── cache.class.php ├── composer.json └── license.txt /README.markdown: -------------------------------------------------------------------------------- 1 | # Simple PHP Cache # 2 | 3 | ## About ## 4 | 5 | A light, simple but powerful PHP5 Cache Class which uses the filesystem for caching. 6 | Your feedback is always welcome. 7 | 8 | ## Requirements ## 9 | 10 | - PHP 5.2.x or higher 11 | 12 | ## Introduction ## 13 | 14 | Basically the caching class stores its data in files in the JSON format. These files will be created if you store data under a Cache name. 15 | 16 | If you set a new Cache name with `setCache()`, a new cache file will be generated. The Cache will store all further data in the new file. The Setter method allows you to switch between the different Cache files. 17 | 18 | ## Quick Start ## 19 | 20 | ### Setup Cache class ### 21 | 22 | It's not much trouble to setup the Cache. 23 | First create a writable directory `cache/` and include the Cache class: 24 | 25 | ```php 26 | 32 | ``` 33 | 34 | Now we've setup the Cache instance and can start caching! 35 | 36 | ```php 37 | store('hello', 'Hello World!'); 40 | 41 | // generate a new cache file with the name 'newcache' 42 | $c->setCache('newcache'); 43 | 44 | // store an array 45 | $c->store('movies', array( 46 | 'description' => 'Movies on TV', 47 | 'action' => array( 48 | 'Tropic Thunder', 49 | 'Bad Boys', 50 | 'Crank' 51 | ) 52 | )); 53 | 54 | // get cached data by its key 55 | $result = $c->retrieve('movies'); 56 | 57 | // display the cached array 58 | echo '
';
 59 |     print_r($result);
 60 |     echo '
';
 61 |     
 62 |     // grab array entry
 63 |     $description = $result['description'];
 64 |     
 65 |     // switch back to the first cache
 66 |     $c->setCache('mycache');
 67 |     
 68 |     // update entry by simply overwriting an existing key
 69 |     $c->store('hello', 'Hello everybody out there!');
 70 |     
 71 |     // erase entry by its key
 72 |     $c->erase('hello');
 73 | ?>
 74 | ```
 75 | 
 76 | You can also make use of the Method Chaining feature, introduced in PHP5.  
 77 | So you can do something like that:
 78 | 
 79 | ```php
 80 | setCache('mycache')      // generate new file
 82 |       ->store('hello', 'world')  // store data string
 83 |       ->retrieve('hello');       // retrieve cached data
 84 | ?>
 85 | ```
 86 | 
 87 | ## Available methods ##
 88 | 
 89 | ### Setup the Cache ###
 90 | 
 91 | `new Cache(/)`  
 92 | 
 93 | `string` gives you the basic setup.  
 94 | It's the name of your Cache (standard Cache name is *'default'*):
 95 | 
 96 |     new Cache('YOUR-CACHE-NAME');
 97 | 
 98 | `array` allows you to define multiple optional parameters:
 99 | 
100 |     new Cache(array(
101 |       'name'      => 'YOUR-CACHE-NAME',
102 |       'path'      => 'cache/',
103 |       'extension' => '.cache'
104 |     ));
105 | 
106 | If you don't define a Cache name with the constructor or the `setCache()` method, it'll be 'default'.
107 | 
108 | ### Store data ###
109 | 
110 | `store($key, $data, <$expiration>)`
111 | 
112 | - The `key` value defines a tag with which the cached data will be associated.
113 | - The `data` value can be any type of object (will be serialized).
114 | - The `expiration` value allows you to define an expiration time.
115 | 
116 | To change data you can overwrite it by using the same key identifier.  
117 | Beside the data, the Cache will also store a timestamp.
118 | 
119 | A sample Cache entry looks like this:
120 | 
121 | ```json
122 | {
123 |   "christmas": {
124 |     "time": 1324664631,
125 |     "expire": 28000,
126 |     "data": "s:29:"A great time to bake cookies.";" // serialized
127 |   }
128 | }
129 | ```
130 | 
131 | ### Retrieve data ###
132 | 
133 | `retrieve($key, <$timestamp>)`  
134 | 
135 | Get particular cached data by its key.  
136 | To retrieve the timestamp of a key, set the second parameter to `true`.
137 | 
138 | `retrieveAll(<$meta>)`  
139 | 
140 | This allows you retrieve all the cached data at once. You get the meta data by setting the `$meta` argument to `true`.
141 | 
142 | ### Erase data ###
143 | 
144 | For erasing cached data are these three methods available:
145 | 
146 | - `erase($key)` Erases a single entry by its key.
147 | - `eraseAll()` Erases all entries from the Cache file.
148 | - `eraseExpired()` Erases all expired entries.
149 | 
150 | ```php
151 | eraseExpired() . ' expired items erased!';
154 | ?>
155 | ```
156 | 
157 | ### Check cached data ###
158 | 
159 | `isCached($key)`  
160 | 
161 | Check whether any data is associated with the given key.  
162 | Returns `true` or `false`.
163 | 
164 | ### Set Cache name ###
165 | 
166 | `setCache($name)`  
167 | 
168 | If you want to switch to another Cache or create a new one, then use this method to set a new Cache name.
169 | 
170 | ### Set Cache path ###
171 | 
172 | `setCachePath($path)`  
173 | 
174 | The path to the Cache folder must end with a backslash: `my_path_to_the_cache_folder/`
175 | 
176 | ### Get Cache file path ###
177 | 
178 | `getCacheDir()`  
179 | 
180 | The method returns the path to your current Cache file (the Cache name is always sh1 encoded):
181 | 
182 | ```
183 | cache/7505d64a54e061b7acd54ccd58b49dc43500b635.cache
184 | ```
185 | 
186 | ## Benchmarks ##
187 | 
188 | > If you've done one, please let me know.
189 | 
190 | ## History ##
191 | 
192 | > Upcoming: Simple Cache 2.0  
193 | > Implementation of an internal "soft cache", hash-sum handling and the switch to serialization. Thanks @dariushha for his contribution!
194 | 
195 | **Simple Cache 1.6 - 04/01/2014**
196 | 
197 | - `update` Updated docs.
198 | - `bug` Fixed `retrieveAll()` method to unserialize data.
199 | 
200 | **Simple Cache 1.5 - 01/01/2014**
201 | 
202 | - `feature` added `serialize` / `unserialize` to store any kind of data.
203 | 
204 | **Simple Cache 1.4 - 08/09/2013**
205 | 
206 | - `bug` Fixed loading file twice in `store()` method.
207 | - `bug` Fixed `retrieve()` method - made it fail safe (thanks @dariushha). 
208 | 
209 | **Simple Cache 1.3 - 28/02/2013**
210 | 
211 | - `update` Updated docs for the added `retrieveAll()` method.
212 | - `feature` Added `retrieveAll()` method (thanks @rpnzl).
213 | 
214 | **Simple Cache 1.2 - 09/05/2012**
215 | 
216 | - `update` Formatted code
217 | - `bug` Fixed `isCached()` method so that it works as expected (thanks @TigerWolf).
218 | 
219 | **Simple Cache 1.1 - 01/01/2012**
220 | 
221 | - `change` The extension config has to start now with a dot.
222 | - `feature` Added expiration handling to the `store()` method
223 | - `feature` Added the methods `eraseExpired()` and `eraseAll()`
224 | - `feature` Added method to make sure that a writable directory exists
225 | 
226 | **Simple Cache 1.0 - 29/12/2011**
227 | 
228 | - `release` First public version
229 | - `feature` Added timestamp option to the `retrieve()` method
230 | 
231 | **Simple Cache 0.9 - 25/12/2011**
232 | 
233 | - `update` Added Quick Start guide to the documentation
234 | - `feature` Added Method Chaining possibility
235 | - `bug` Fixed constructor configuration string/array handling
236 | 
237 | **Simple Cache 0.8 - 24/12/2011**
238 | 
239 | - `release` First internal beta version (tested)
240 | - `feature` Added Setter and Getter methods
241 | - `update` Detailed documentation
242 | 
243 | **Simple Cache 0.5 - 22/12/2011**
244 | 
245 | - `release` First internal alpha version
246 | - `update` Small documentation
247 | 
248 | ## Credits ##
249 | 
250 | Copyright (c) 2011-2013 - Programmed by Christian Metz / [@cosenary](http://twitter.com/cosenary)  
251 | Released under the [BSD License](http://www.opensource.org/licenses/bsd-license.php).


--------------------------------------------------------------------------------
/cache.class.php:
--------------------------------------------------------------------------------
  1 | setCache($config);
 47 |       } else if (is_array($config)) {
 48 |         $this->setCache($config['name']);
 49 |         $this->setCachePath($config['path']);
 50 |         $this->setExtension($config['extension']);
 51 |       }
 52 |     }
 53 |   }
 54 | 
 55 |   /**
 56 |    * Check whether data accociated with a key
 57 |    *
 58 |    * @param string $key
 59 |    * @return boolean
 60 |    */
 61 |   public function isCached($key) {
 62 |     if (false != $this->_loadCache()) {
 63 |       $cachedData = $this->_loadCache();
 64 |       return isset($cachedData[$key]['data']);
 65 |     }
 66 |   }
 67 | 
 68 |   /**
 69 |    * Store data in the cache
 70 |    *
 71 |    * @param string $key
 72 |    * @param mixed $data
 73 |    * @param integer [optional] $expiration
 74 |    * @return object
 75 |    */
 76 |   public function store($key, $data, $expiration = 0) {
 77 |     $storeData = array(
 78 |       'time'   => time(),
 79 |       'expire' => $expiration,
 80 |       'data'   => serialize($data)
 81 |     );
 82 |     $dataArray = $this->_loadCache();
 83 |     if (true === is_array($dataArray)) {
 84 |       $dataArray[$key] = $storeData;
 85 |     } else {
 86 |       $dataArray = array($key => $storeData);
 87 |     }
 88 |     $cacheData = json_encode($dataArray);
 89 |     file_put_contents($this->getCacheDir(), $cacheData);
 90 |     return $this;
 91 |   }
 92 | 
 93 |   /**
 94 |    * Retrieve cached data by its key
 95 |    * 
 96 |    * @param string $key
 97 |    * @param boolean [optional] $timestamp
 98 |    * @return string
 99 |    */
100 |   public function retrieve($key, $timestamp = false) {
101 |     $cachedData = $this->_loadCache();
102 |     (false === $timestamp) ? $type = 'data' : $type = 'time';
103 |     if (!isset($cachedData[$key][$type])) return null; 
104 |     return unserialize($cachedData[$key][$type]);
105 |   }
106 | 
107 |   /**
108 |    * Retrieve all cached data
109 |    * 
110 |    * @param boolean [optional] $meta
111 |    * @return array
112 |    */
113 |   public function retrieveAll($meta = false) {
114 |     if ($meta === false) {
115 |       $results = array();
116 |       $cachedData = $this->_loadCache();
117 |       if ($cachedData) {
118 |         foreach ($cachedData as $k => $v) {
119 |           $results[$k] = unserialize($v['data']);
120 |         }
121 |       }
122 |       return $results;
123 |     } else {
124 |       return $this->_loadCache();
125 |     }
126 |   }
127 | 
128 |   /**
129 |    * Erase cached entry by its key
130 |    * 
131 |    * @param string $key
132 |    * @return object
133 |    */
134 |   public function erase($key) {
135 |     $cacheData = $this->_loadCache();
136 |     if (true === is_array($cacheData)) {
137 |       if (true === isset($cacheData[$key])) {
138 |         unset($cacheData[$key]);
139 |         $cacheData = json_encode($cacheData);
140 |         file_put_contents($this->getCacheDir(), $cacheData);
141 |       } else {
142 |         throw new Exception("Error: erase() - Key '{$key}' not found.");
143 |       }
144 |     }
145 |     return $this;
146 |   }
147 | 
148 |   /**
149 |    * Erase all expired entries
150 |    * 
151 |    * @return integer
152 |    */
153 |   public function eraseExpired() {
154 |     $cacheData = $this->_loadCache();
155 |     if (true === is_array($cacheData)) {
156 |       $counter = 0;
157 |       foreach ($cacheData as $key => $entry) {
158 |         if (true === $this->_checkExpired($entry['time'], $entry['expire'])) {
159 |           unset($cacheData[$key]);
160 |           $counter++;
161 |         }
162 |       }
163 |       if ($counter > 0) {
164 |         $cacheData = json_encode($cacheData);
165 |         file_put_contents($this->getCacheDir(), $cacheData);
166 |       }
167 |       return $counter;
168 |     }
169 |   }
170 | 
171 |   /**
172 |    * Erase all cached entries
173 |    * 
174 |    * @return object
175 |    */
176 |   public function eraseAll() {
177 |     $cacheDir = $this->getCacheDir();
178 |     if (true === file_exists($cacheDir)) {
179 |       $cacheFile = fopen($cacheDir, 'w');
180 |       fclose($cacheFile);
181 |     }
182 |     return $this;
183 |   }
184 | 
185 |   /**
186 |    * Load appointed cache
187 |    * 
188 |    * @return mixed
189 |    */
190 |   private function _loadCache() {
191 |     if (true === file_exists($this->getCacheDir())) {
192 |       $file = file_get_contents($this->getCacheDir());
193 |       return json_decode($file, true);
194 |     } else {
195 |       return false;
196 |     }
197 |   }
198 | 
199 |   /**
200 |    * Get the cache directory path
201 |    * 
202 |    * @return string
203 |    */
204 |   public function getCacheDir() {
205 |     if (true === $this->_checkCacheDir()) {
206 |       $filename = $this->getCache();
207 |       $filename = preg_replace('/[^0-9a-z\.\_\-]/i', '', strtolower($filename));
208 |       return $this->getCachePath() . $this->_getHash($filename) . $this->getExtension();
209 |     }
210 |   }
211 | 
212 |   /**
213 |    * Get the filename hash
214 |    * 
215 |    * @return string
216 |    */
217 |   private function _getHash($filename) {
218 |     return sha1($filename);
219 |   }
220 | 
221 |   /**
222 |    * Check whether a timestamp is still in the duration 
223 |    * 
224 |    * @param integer $timestamp
225 |    * @param integer $expiration
226 |    * @return boolean
227 |    */
228 |   private function _checkExpired($timestamp, $expiration) {
229 |     $result = false;
230 |     if ($expiration !== 0) {
231 |       $timeDiff = time() - $timestamp;
232 |       ($timeDiff > $expiration) ? $result = true : $result = false;
233 |     }
234 |     return $result;
235 |   }
236 | 
237 |   /**
238 |    * Check if a writable cache directory exists and if not create a new one
239 |    * 
240 |    * @return boolean
241 |    */
242 |   private function _checkCacheDir() {
243 |     if (!is_dir($this->getCachePath()) && !mkdir($this->getCachePath(), 0775, true)) {
244 |       throw new Exception('Unable to create cache directory ' . $this->getCachePath());
245 |     } elseif (!is_readable($this->getCachePath()) || !is_writable($this->getCachePath())) {
246 |       if (!chmod($this->getCachePath(), 0775)) {
247 |         throw new Exception($this->getCachePath() . ' must be readable and writeable');
248 |       }
249 |     }
250 |     return true;
251 |   }
252 | 
253 |   /**
254 |    * Cache path Setter
255 |    * 
256 |    * @param string $path
257 |    * @return object
258 |    */
259 |   public function setCachePath($path) {
260 |     $this->_cachepath = $path;
261 |     return $this;
262 |   }
263 | 
264 |   /**
265 |    * Cache path Getter
266 |    * 
267 |    * @return string
268 |    */
269 |   public function getCachePath() {
270 |     return $this->_cachepath;
271 |   }
272 | 
273 |   /**
274 |    * Cache name Setter
275 |    * 
276 |    * @param string $name
277 |    * @return object
278 |    */
279 |   public function setCache($name) {
280 |     $this->_cachename = $name;
281 |     return $this;
282 |   }
283 | 
284 |   /**
285 |    * Cache name Getter
286 |    * 
287 |    * @return void
288 |    */
289 |   public function getCache() {
290 |     return $this->_cachename;
291 |   }
292 | 
293 |   /**
294 |    * Cache file extension Setter
295 |    * 
296 |    * @param string $ext
297 |    * @return object
298 |    */
299 |   public function setExtension($ext) {
300 |     $this->_extension = $ext;
301 |     return $this;
302 |   }
303 | 
304 |   /**
305 |    * Cache file extension Getter
306 |    * 
307 |    * @return string
308 |    */
309 |   public function getExtension() {
310 |     return $this->_extension;
311 |   }
312 | 
313 | }
314 | 


--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
 1 | {
 2 | 	"name": "cosenary/simple-php-cache",
 3 | 	"type": "library",
 4 | 	"description": "A light, simple but powerful PHP5 Cache Class which uses the filesystem for caching.",
 5 | 	"keywords": ["cache", "simple", "filesystem", "json"],
 6 | 	"homepage": "https://github.com/cosenary/Simple-PHP-Cache",
 7 | 	"license": "BSD",
 8 | 	"authors": [
 9 | 		{
10 | 			"name": "Christian Metz",
11 | 			"email": "christian-metz1@gmx.net",
12 | 			"homepage": "http://metzweb.net"
13 | 		}
14 | 	],
15 | 	"require": {
16 | 		"php": ">=5.2.0",
17 | 		"ext-curl": "*"
18 | 	},
19 | 	"autoload": {
20 | 		"classmap": [
21 | 			"."
22 | 		]
23 | 	}
24 | }


--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
 1 | Copyright (c) 2012, Christian Metz
 2 | All rights reserved.
 3 | 
 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 5 | 
 6 |     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 7 |     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 8 |     * Neither the name of the organisation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 9 | 
10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


--------------------------------------------------------------------------------