[ Index ]
 

Code source de PHP PEAR 1.4.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/Cache/ -> Container.php (source)

   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  ?>


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7