[ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 // +----------------------------------------------------------------------+ 3 // | PEAR :: Cache | 4 // +----------------------------------------------------------------------+ 5 // | Copyright (c) 1997-2003 The PHP Group | 6 // +----------------------------------------------------------------------+ 7 // | This source file is subject to version 2.0 of the PHP license, | 8 // | that is bundled with this package in the file LICENSE, and is | 9 // | available at through the world-wide-web at | 10 // | http://www.php.net/license/2_02.txt. | 11 // | If you did not receive a copy of the PHP license and are unable to | 12 // | obtain it through the world-wide-web, please send a note to | 13 // | license@php.net so we can mail you a copy immediately. | 14 // +----------------------------------------------------------------------+ 15 // | Authors: Ulf Wendel <ulf.wendel@phpdoc.de> | 16 // | Sebastian Bergmann <sb@sebastian-bergmann.de> | 17 // | Christian Stocker <chregu@phant.ch> | 18 // +----------------------------------------------------------------------+ 19 // 20 // $Id: Container.php,v 1.4 2003/01/04 11:54:45 mj Exp $ 21 22 require_once 'Cache/Error.php'; 23 24 /** 25 * Common base class of all cache storage container. 26 * 27 * To speed up things we do a preload you should know about, otherwise it might 28 * play you a trick. The Cache controller classes (Cache/Cache, Cache/Output, ...) 29 * usually do something like is (isCached($id) && !isExpired($id)) return $container->load($id). 30 * if you implement isCached(), isExpired() and load() straight ahead, each of this 31 * functions will result in a storage medium (db, file,...) access. This generates too much load. 32 * Now, a simple speculative preload should saves time in most cases. Whenever 33 * one of the mentioned methods is invoked we preload the cached dataset into class variables. 34 * That means that we have only one storage medium access for the sequence 35 * (isCached($id) && !isExpired($id)) return $container->load($id). 36 * The bad thing is that the preloaded data might be outdated meanwhile, which is 37 * unlikely but for you power users, be warned. If you do not want the preload 38 * you should switch it off by setting the class variable $preload to false. Anyway, this is 39 * not recommended! 40 * 41 * @author Ulf Wendel <ulf.wendel@phpdoc.de> 42 * @version $Id: Container.php,v 1.4 2003/01/04 11:54:45 mj Exp $ 43 * @package Cache 44 * @access public 45 * @abstract 46 */ 47 class Cache_Container { 48 49 /** 50 * Flag indicating wheter to preload datasets. 51 * 52 * See the class description for more details. 53 * 54 * @var boolean 55 */ 56 var $preload = true; 57 58 /** 59 * ID of a preloaded dataset 60 * 61 * @var string 62 */ 63 var $id = ''; 64 65 /** 66 * Cache group of a preloaded dataset 67 * 68 * @var string 69 */ 70 var $group = ''; 71 72 /** 73 * Expiration timestamp of a preloaded dataset. 74 * 75 * @var integer 0 means never, endless 76 */ 77 var $expires = 0; 78 79 /** 80 * Value of a preloaded dataset. 81 * 82 * @var string 83 */ 84 var $cachedata = ''; 85 86 /** 87 * Preloaded userdata field. 88 * 89 * @var string 90 */ 91 var $userdata = ''; 92 93 /** 94 * Flag indicating that the dataset requested for preloading is unknown. 95 * 96 * @var boolean 97 */ 98 var $unknown = true; 99 100 /** 101 * Encoding mode for cache data: base64 or addslashes() (slash). 102 * 103 * @var string base64 or slash 104 */ 105 var $encoding_mode = 'base64'; 106 107 /** 108 * Highwater mark - maximum space required by all cache entries. 109 * 110 * Whenever the garbage collection runs it checks the amount of space 111 * required by all cache entries. If it's more than n (highwater) bytes 112 * the garbage collection deletes as many entries as necessary to reach the 113 * lowwater mark. 114 * 115 * @var int 116 * @see lowwater 117 */ 118 var $highwater = 2048000; 119 120 121 /** 122 * Lowwater mark 123 * 124 * @var int 125 * @see highwater 126 */ 127 var $lowwater = 1536000; 128 129 130 /** 131 * Options that can be set in every derived class using it's constructor. 132 * 133 * @var array 134 */ 135 var $allowed_options = array('encoding_mode', 'highwater', 'lowwater'); 136 137 138 /** 139 * Loads a dataset from the cache. 140 * 141 * @param string dataset ID 142 * @param string cache group 143 * @return mixed dataset value or NULL on failure 144 * @access public 145 */ 146 function load($id, $group) { 147 if ($this->preload) { 148 if ($this->id != $id || $this->group != $group) 149 $this->preload($id, $group); 150 151 return $this->cachedata; 152 } else { 153 list( , $data, ) = $this->fetch($id, $group); 154 return $data; 155 } 156 } // end func load 157 158 /** 159 * Returns the userdata field of a cached data set. 160 * 161 * @param string dataset ID 162 * @param string cache group 163 * @return string userdata 164 * @access public 165 */ 166 function getUserdata($id, $group) { 167 if ($this->preload) { 168 if ($this->id != $id || $this->group != $group) 169 $this->preload($id, $group); 170 171 return $this->userdata; 172 } else { 173 list( , , $userdata) = $this->fetch($id, $group); 174 return $userdata; 175 } 176 } // end func getUserdata 177 178 /** 179 * Checks if a dataset is expired. 180 * 181 * @param string dataset ID 182 * @param string cache group 183 * @param integer maximum age timestamp 184 * @return boolean 185 * @access public 186 */ 187 function isExpired($id, $group, $max_age) { 188 if ($this->preload) { 189 if ($this->id != $id || $this->group != $group) 190 $this->preload($id, $group); 191 192 if ($this->unknown) 193 return false; 194 } else { 195 // check if at all it is cached 196 if (!$this->isCached($id, $group)) 197 return false; 198 199 // I'm lazy... 200 list($this->expires, , ) = $this->fetch($id, $group); 201 } 202 203 // endless 204 if (0 == $this->expires) 205 return false; 206 207 // you feel fine, Ulf? 208 if ($expired = ($this->expires <= time() || ($max_age && ($this->expires <= $max_age))) ) { 209 210 $this->remove($id, $group); 211 $this->flushPreload(); 212 } 213 return $expired; 214 } // end func isExpired 215 216 /** 217 * Checks if a dataset is cached. 218 * 219 * @param string dataset ID 220 * @param string cache group 221 * @return boolean 222 */ 223 function isCached($id, $group) { 224 if ($this->preload) { 225 if ($this->id != $id || $this->group != $group) 226 $this->preload($id, $group); 227 228 return !($this->unknown); 229 } else { 230 return $this->idExists($id, $group); 231 } 232 } // end func isCached 233 234 // 235 // abstract methods 236 // 237 238 /** 239 * Fetches a dataset from the storage medium. 240 * 241 * @param string dataset ID 242 * @param string cache group 243 * @return array format: [expire date, cached data, user data] 244 * @throws Cache_Error 245 * @abstract 246 */ 247 function fetch($id, $group) { 248 return array(NULL, NULL, NULL); 249 } // end func fetch 250 251 /** 252 * Stores a dataset. 253 * 254 * @param string dataset ID 255 * @param mixed data to store 256 * @param mixed userdefined expire date 257 * @param string cache group 258 * @param string additional userdefined data 259 * @return boolean 260 * @throws Cache_Error 261 * @access public 262 * @abstract 263 */ 264 function save($id, $data, $expire, $group, $userdata) { 265 // QUESTION: Should we update the preload buffer instead? 266 // Don't think so as the sequence save()/load() is unlikely. 267 $this->flushPreload($id, $group); 268 269 return NULL; 270 } // end func save 271 272 /** 273 * Removes a dataset. 274 * 275 * @param string dataset ID 276 * @param string cache group 277 * @return boolean 278 * @access public 279 * @abstract 280 */ 281 function remove($id, $group) { 282 $this->flushPreload($id, $group); 283 return NULL; 284 } // end func remove 285 286 /** 287 * Flushes the cache - removes all caches datasets from the cache. 288 * 289 * @param string If a cache group is given only the group will be flushed 290 * @return integer Number of removed datasets, -1 on failure 291 * @access public 292 * @abstract 293 */ 294 function flush($group) { 295 $this->flushPreload(); 296 return NULL; 297 } // end func flush 298 299 /** 300 * Checks if a dataset exists. 301 * 302 * @param string dataset ID 303 * @param string cache group 304 * @return boolean 305 * @access public 306 * @abstract 307 */ 308 function idExists($id, $group) { 309 return NULL; 310 } // end func idExists 311 312 /** 313 * Starts the garbage collection. 314 * 315 * @access public 316 * @abstract 317 */ 318 function garbageCollection() { 319 $this->flushPreload(); 320 } // end func garbageCollection 321 322 /** 323 * Does a speculative preload of a dataset 324 * 325 * @param string dataset ID 326 * @param string cache group 327 * @return boolean 328 */ 329 function preload($id, $group) { 330 // whatever happens, remember the preloaded ID 331 $this->id = $id; 332 $this->group = $group; 333 334 list($this->expires, $this->cachedata, $this->userdata) = $this->fetch($id, $group); 335 336 if (NULL === $this->expires) { 337 // Uuups, unknown ID 338 $this->flushPreload(); 339 340 return false; 341 } 342 343 $this->unknown = false; 344 345 return true; 346 } // end func preload 347 348 /** 349 * Flushes the internal preload buffer. 350 * 351 * save(), remove() and flush() must call this method 352 * to preevent differences between the preloaded values and 353 * the real cache contents. 354 * 355 * @param string dataset ID, if left out the preloaded values will be flushed. 356 * If given the preloaded values will only be flushed if they are 357 * equal to the given id and group 358 * @param string cache group 359 * @see preload() 360 */ 361 function flushPreload($id = '', $group = 'default') { 362 if (!$id || ($this->id == $id && $this->group == $group)) { 363 // clear the internal preload values 364 $this->id = ''; 365 $this->group = ''; 366 $this->cachedata = ''; 367 $this->userdata = ''; 368 $this->expires = -1; 369 $this->unknown = true; 370 } 371 } // end func flushPreload 372 373 /** 374 * Imports the requested datafields as object variables if allowed 375 * 376 * @param array List of fields to be imported as object variables 377 * @param array List of allowed datafields 378 */ 379 function setOptions($requested, $allowed) { 380 foreach ($allowed as $k => $field) 381 if (isset($requested[$field])) 382 $this->$field = $requested[$field]; 383 384 } // end func setOptions 385 386 /** 387 * Encodes the data for the storage container. 388 * 389 * @var mixed data to encode 390 */ 391 function encode($data) { 392 if ('base64' == $this->encoding_mode) 393 return base64_encode(serialize($data)); 394 else 395 return serialize($data); 396 } // end func encode 397 398 399 /** 400 * Decodes the data from the storage container. 401 * 402 * @var mixed 403 */ 404 function decode($data) { 405 if ('base64' == $this->encoding_mode) 406 return unserialize(base64_decode($data)); 407 else 408 return unserialize($data); 409 } // end func decode 410 411 412 /** 413 * Translates human readable/relative times in unixtime 414 * 415 * @param mixed can be in the following formats: 416 * human readable : yyyymmddhhmm[ss]] eg: 20010308095100 417 * relative in seconds (1) : +xx eg: +10 418 * relative in seconds (2) : x < 946681200 eg: 10 419 * absolute unixtime : x < 2147483648 eg: 2147483648 420 * see comments in code for details 421 * @return integer unix timestamp 422 */ 423 function getExpiresAbsolute($expires) 424 { 425 if (!$expires) 426 return 0; 427 //for api-compatibility, one has not to provide a "+", 428 // if integer is < 946681200 (= Jan 01 2000 00:00:00) 429 if ('+' == $expires[0] || $expires < 946681200) 430 { 431 return(time() + $expires); 432 } 433 //if integer is < 100000000000 (= in 3140 years), 434 // it must be an absolut unixtime 435 // (since the "human readable" definition asks for a higher number) 436 elseif ($expires < 100000000000) 437 { 438 return $expires; 439 } 440 // else it's "human readable"; 441 else 442 { 443 $year = substr($expires, 0, 4); 444 $month = substr($expires, 4, 2); 445 $day = substr($expires, 6, 2); 446 $hour = substr($expires, 8, 2); 447 $minute = substr($expires, 10, 2); 448 $second = substr($expires, 12, 2); 449 return mktime($hour, $minute, $second, $month, $day, $year); 450 } 451 452 } // end func getExpireAbsolute 453 454 } // end class Container 455 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |