[ Index ]
 

Code source de PRADO 3.0.6

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

title

Body

[fermer]

/framework/I18N/core/ -> TCache_Lite.php (source)

   1  <?php
   2  
   3  /**
   4   * TCache_Lite class file.
   5   *
   6   * This program is free software; you can redistribute it and/or modify
   7   * it under the terms of the BSD License.
   8   *
   9   * Copyright(c) 2004 by Qiang Xue. All rights reserved.
  10   *
  11   * To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue}
  12   * The latest version of PRADO can be obtained from:
  13   * {@link http://prado.sourceforge.net/}
  14   *
  15   * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
  16   * @version $Revision: 1.3 $  $Date: 2005/10/09 10:24:12 $
  17   * @package System.I18N.core
  18   */
  19  
  20  /**
  21  * Fast, light and safe Cache Class
  22  *
  23  * TCache_Lite is a fast, light and safe cache system. It's optimized
  24  * for file containers. It is fast and safe (because it uses file
  25  * locking and/or anti-corruption tests).
  26  *
  27  * There are some examples in the 'docs/examples' file
  28  * Technical choices are described in the 'docs/technical' file
  29  *
  30  * A tutorial is available in english at this url :
  31  * http://www.pearfr.org/index.php/en/article/cache_lite
  32  * (big thanks to Pierre-Alain Joye for the translation)
  33  *
  34  * The same tutorial is also available in french at this url :
  35  * http://www.pearfr.org/index.php/fr/article/cache_lite
  36  *
  37  * Memory Caching is from an original idea of
  38  * Mike BENOIT <ipso@snappymail.ca>
  39  *
  40  * @package System.I18N.core
  41  * @version $Id: TCache_Lite.php 1397 2006-09-07 07:55:53Z wei $
  42  * @author Fabien MARTY <fab@php.net>
  43  * @copyright  1997-2005 The PHP Group
  44  * @license    http://www.gnu.org/copyleft/lesser.html GNU LGPL
  45  * @link       http://pear.php.net/package/Cache_Lite
  46  */
  47  class TCache_Lite
  48  {
  49  
  50      // --- Private properties ---
  51  
  52      /**
  53      * Directory where to put the cache files
  54      * (make sure to add a trailing slash)
  55      *
  56      * @var string $_cacheDir
  57      */
  58      protected $_cacheDir = '/tmp/';
  59  
  60      /**
  61      * Enable / disable caching
  62      *
  63      * (can be very usefull for the debug of cached scripts)
  64      *
  65      * @var boolean $_caching
  66      */
  67      protected $_caching = true;
  68  
  69      /**
  70      * Cache lifetime (in seconds)
  71      *
  72      * @var int $_lifeTime
  73      */
  74      protected $_lifeTime = 3600;
  75  
  76      /**
  77      * Enable / disable fileLocking
  78      *
  79      * (can avoid cache corruption under bad circumstances)
  80      *
  81      * @var boolean $_fileLocking
  82      */
  83      protected $_fileLocking = true;
  84  
  85      /**
  86      * Timestamp of the last valid cache
  87      *
  88      * @var int $_refreshTime
  89      */
  90      protected $_refreshTime;
  91  
  92      /**
  93      * File name (with path)
  94      *
  95      * @var string $_file
  96      */
  97      protected $_file;
  98  
  99      /**
 100      * Enable / disable write control (the cache is read just after writing
 101      * to detect corrupt entries)
 102      *
 103      * Enable write control will lightly slow the cache writing but not the
 104      * cache reading. Write control can detect some corrupt cache files but
 105      * maybe it's not a perfect control
 106      *
 107      * @var boolean $_writeControl
 108      */
 109      protected $_writeControl = true;
 110  
 111      /**
 112      * Enable / disable read control
 113      *
 114      * If enabled, a control key is embeded in cache file and this key is
 115      * compared with the one calculated after the reading.
 116      *
 117      * @var boolean $_writeControl
 118      */
 119      protected $_readControl = true;
 120  
 121      /**
 122      * Type of read control (only if read control is enabled)
 123      *
 124      * Available values are :
 125      * 'md5' for a md5 hash control (best but slowest)
 126      * 'crc32' for a crc32 hash control (lightly less safe but faster,
 127      * better choice)
 128      * 'strlen' for a length only test (fastest)
 129      *
 130      * @var boolean $_readControlType
 131      */
 132      protected $_readControlType = 'crc32';
 133  
 134      /**
 135      * Current cache id
 136      *
 137      * @var string $_id
 138      */
 139      protected $_id;
 140  
 141      /**
 142      * Current cache group
 143      *
 144      * @var string $_group
 145      */
 146      protected $_group;
 147  
 148      /**
 149      * Enable / Disable "Memory Caching"
 150      *
 151      * NB : There is no lifetime for memory caching !
 152      *
 153      * @var boolean $_memoryCaching
 154      */
 155      protected $_memoryCaching = false;
 156  
 157      /**
 158      * Enable / Disable "Only Memory Caching"
 159      * (be carefull, memory caching is "beta quality")
 160      *
 161      * @var boolean $_onlyMemoryCaching
 162      */
 163      protected $_onlyMemoryCaching = false;
 164  
 165      /**
 166      * Memory caching array
 167      *
 168      * @var array $_memoryCachingArray
 169      */
 170      protected $_memoryCachingArray = array();
 171  
 172      /**
 173      * Memory caching counter
 174      *
 175      * @var int $memoryCachingCounter
 176      */
 177      protected $_memoryCachingCounter = 0;
 178  
 179      /**
 180      * Memory caching limit
 181      *
 182      * @var int $memoryCachingLimit
 183      */
 184      protected $_memoryCachingLimit = 1000;
 185  
 186      /**
 187      * File Name protection
 188      *
 189      * if set to true, you can use any cache id or group name
 190      * if set to false, it can be faster but cache ids and group names
 191      * will be used directly in cache file names so be carefull with
 192      * special characters...
 193      *
 194      * @var boolean $fileNameProtection
 195      */
 196      protected $_fileNameProtection = true;
 197  
 198      /**
 199      * Enable / disable automatic serialization
 200      *
 201      * it can be used to save directly datas which aren't strings
 202      * (but it's slower)
 203      *
 204      * @var boolean $_serialize
 205      */
 206      protected $_automaticSerialization = false;
 207  
 208      // --- Public methods ---
 209  
 210      /**
 211      * Constructor
 212      *
 213      * $options is an assoc. Available options are :
 214      * $options = array(
 215      * 'cacheDir' => directory where to put the cache files (string),
 216      * 'caching' => enable / disable caching (boolean),
 217      * 'lifeTime' => cache lifetime in seconds (int),
 218      * 'fileLocking' => enable / disable fileLocking (boolean),
 219      * 'writeControl' => enable / disable write control (boolean),
 220      * 'readControl' => enable / disable read control (boolean),
 221      * 'readControlType' => type of read control 'crc32', 'md5', 'strlen',
 222      * 'memoryCaching' => enable / disable memory caching (boolean),
 223      * 'onlyMemoryCaching' => enable / disable only memory caching (boolean),
 224      * 'memoryCachingLimit' => max nbr of records in memory caching (int),
 225      * 'fileNameProtection' => enable / disable file name protection (boolean),
 226      * 'automaticSerialization' => enable / disable serialization (boolean)
 227      * );
 228      *
 229      * @param array $options options
 230      * @access public
 231      */
 232      function TCache_Lite($options = array(null))
 233      {
 234          $availableOptions = array(    'automaticSerialization',
 235                                      'fileNameProtection',
 236                                      'memoryCaching',
 237                                      'onlyMemoryCaching',
 238                                      'memoryCachingLimit',
 239                                      'cacheDir',
 240                                      'caching',
 241                                      'lifeTime',
 242                                      'fileLocking',
 243                                      'writeControl',
 244                                      'readControl',
 245                                      'readControlType');
 246          foreach($options as $key => $value) {
 247              if(in_array($key, $availableOptions)) {
 248                  $property = '_'.$key;
 249                  $this->$property = $value;
 250              }
 251          }
 252          $this->_refreshTime = time() - $this->_lifeTime;
 253      }
 254  
 255      /**
 256      * Test if a cache is available and (if yes) return it
 257      *
 258      * @param string $id cache id
 259      * @param string $group name of the cache group
 260      * @param boolean $doNotTestCacheValidity if set to true, the cache
 261      * validity won't be tested
 262      * @return string data of the cache (or false if no cache available)
 263      * @access public
 264      */
 265      function get($id, $group = 'default', $doNotTestCacheValidity = false)
 266      {
 267          $this->_id = $id;
 268          $this->_group = $group;
 269          $data = false;
 270          if ($this->_caching) {
 271              $this->_setFileName($id, $group);
 272              if ($this->_memoryCaching) {
 273                  if (isset($this->_memoryCachingArray[$this->_file])) {
 274                      if ($this->_automaticSerialization) {
 275                          return unserialize(
 276                                      $this->_memoryCachingArray[$this->_file]);
 277                      } else {
 278                          return $this->_memoryCachingArray[$this->_file];
 279                      }
 280                  } else {
 281                      if ($this->_onlyMemoryCaching) {
 282                          return false;
 283                      }
 284                  }
 285              }
 286              if ($doNotTestCacheValidity) {
 287                  if (file_exists($this->_file)) {
 288                      $data = $this->_read();
 289                  }
 290              } else {
 291                  if (@filemtime($this->_file) > $this->_refreshTime) {
 292                      $data = $this->_read();
 293                  }
 294              }
 295              if (($data) and ($this->_memoryCaching)) {
 296                  $this->_memoryCacheAdd($this->_file, $data);
 297              }
 298              if ($this->_automaticSerialization && is_string($data)) {
 299                  $data = unserialize($data);
 300              }
 301              return $data;
 302          }
 303          return false;
 304      }
 305  
 306      /**
 307      * Save some data in a cache file
 308      *
 309      * @param string $data data to put in cache (can be another type than strings
 310      * if automaticSerialization is on)
 311      * @param string $id cache id
 312      * @param string $group name of the cache group
 313      * @return boolean true if no problem
 314      * @access public
 315      */
 316      function save($data, $id = null, $group = 'default')
 317      {
 318          if ($this->_caching) {
 319              if ($this->_automaticSerialization) {
 320                  $data = serialize($data);
 321              }
 322              if (isset($id)) {
 323                  $this->_setFileName($id, $group);
 324              }
 325              if ($this->_memoryCaching) {
 326                  $this->_memoryCacheAdd($this->_file, $data);
 327                  if ($this->_onlyMemoryCaching) {
 328                      return true;
 329                  }
 330              }
 331              if ($this->_writeControl) {
 332                  if (!$this->_writeAndControl($data)) {
 333                      @touch($this->_file, time() - 2*abs($this->_lifeTime));
 334                      return false;
 335                  } else {
 336                      return true;
 337                  }
 338              } else {
 339                  return $this->_write($data);
 340              }
 341          }
 342          return false;
 343      }
 344  
 345      /**
 346      * Remove a cache file
 347      *
 348      * @param string $id cache id
 349      * @param string $group name of the cache group
 350      * @return boolean true if no problem
 351      * @access public
 352      */
 353      function remove($id, $group = 'default')
 354      {
 355          $this->_setFileName($id, $group);
 356          if (!@unlink($this->_file)) {
 357              $this->raiseError('TCache_Lite : Unable to remove cache !', -3);
 358              return false;
 359          }
 360          return true;
 361      }
 362  
 363      /**
 364      * Clean the cache
 365      *
 366      * if no group is specified all cache files will be destroyed
 367      * else only cache files of the specified group will be destroyed
 368      *
 369      * @param string $group name of the cache group
 370      * @return boolean true if no problem
 371      * @access public
 372      */
 373      function clean($group = false)
 374      {
 375          if ($this->_fileNameProtection) {
 376              $motif = ($group) ? 'cache_'.md5($group).'_' : 'cache_';
 377          } else {
 378              $motif = ($group) ? 'cache_'.$group.'_' : 'cache_';
 379          }
 380          if ($this->_memoryCaching) {
 381              while (list($key, $value) = each($this->_memoryCaching)) {
 382                  if (strpos($key, $motif, 0)) {
 383                      unset($this->_memoryCaching[$key]);
 384                      $this->_memoryCachingCounter =
 385                              $this->_memoryCachingCounter - 1;
 386                  }
 387              }
 388              if ($this->_onlyMemoryCaching) {
 389                  return true;
 390              }
 391          }
 392          if (!($dh = opendir($this->_cacheDir))) {
 393              $this->raiseError('TCache_Lite : Unable to open cache directory !');
 394              return false;
 395          }
 396          while ($file = readdir($dh)) {
 397              if (($file != '.') && ($file != '..')) {
 398                  $file = $this->_cacheDir . $file;
 399                  if (is_file($file)) {
 400                      if (strpos($file, $motif, 0)) {
 401                          if (!@unlink($file)) {
 402               $this->raiseError('Cache_Lite : Unable to remove cache !', -3);
 403                              return false;
 404                          }
 405                      }
 406                  }
 407              }
 408          }
 409          return true;
 410      }
 411  
 412          /**
 413      * Set a new life time
 414      *
 415      * @param int $newLifeTime new life time (in seconds)
 416      * @access public
 417      */
 418      function setLifeTime($newLifeTime)
 419      {
 420          $this->_lifeTime = $newLifeTime;
 421          $this->_refreshTime = time() - $newLifeTime;
 422      }
 423  
 424      /**
 425      *
 426      * @access public
 427      */
 428      function saveMemoryCachingState($id, $group = 'default')
 429      {
 430          if ($this->_caching) {
 431              $array = array(
 432                  'counter' => $this->_memoryCachingCounter,
 433                  'array' => $this->_memoryCachingState
 434              );
 435              $data = serialize($array);
 436              $this->save($data, $id, $group);
 437          }
 438      }
 439  
 440      /**
 441      *
 442      * @access public
 443      */
 444      function getMemoryCachingState($id, $group = 'default',
 445                                      $doNotTestCacheValidity = false)
 446      {
 447          if ($this->_caching) {
 448              if ($data = $this->get($id, $group, $doNotTestCacheValidity))
 449              {
 450                  $array = unserialize($data);
 451                  $this->_memoryCachingCounter = $array['counter'];
 452                  $this->_memoryCachingArray = $array['array'];
 453              }
 454          }
 455      }
 456  
 457      /**
 458      * Return the cache last modification time
 459      *
 460      * BE CAREFUL : THIS METHOD IS FOR HACKING ONLY !
 461      *
 462      * @return int last modification time
 463      */
 464      function lastModified() {
 465          return filemtime($this->cache->_file);
 466      }
 467  
 468      /**
 469      * Trigger a PEAR error
 470      *
 471      * To improve performances, the PEAR.php file is included dynamically.
 472      * The file is so included only when an error is triggered. So, in most
 473      * cases, the file isn't included and perfs are much better.
 474      *
 475      * @param string $msg error message
 476      * @param int $code error code
 477      * @access public
 478      */
 479      function raiseError($msg, $code)
 480      {
 481         throw new Exception($msg);
 482      }
 483  
 484      // --- Private methods ---
 485  
 486      /**
 487      *
 488      * @access private
 489      */
 490      function _memoryCacheAdd($id, $data)
 491      {
 492          $this->_memoryCachingArray[$this->_file] = $data;
 493          if ($this->_memoryCachingCounter >= $this->_memoryCachingLimit) {
 494              list($key, $value) = each($this->_memoryCachingArray);
 495              unset($this->_memoryCachingArray[$key]);
 496          } else {
 497              $this->_memoryCachingCounter = $this->_memoryCachingCounter + 1;
 498          }
 499      }
 500  
 501      /**
 502      * Make a file name (with path)
 503      *
 504      * @param string $id cache id
 505      * @param string $group name of the group
 506      * @access private
 507      */
 508      function _setFileName($id, $group)
 509      {
 510          if ($this->_fileNameProtection) {
 511              $this->_file = ($this->_cacheDir.'cache_'.md5($group).'_'
 512                                      .md5($id));
 513          } else {
 514              $this->_file = $this->_cacheDir.'cache_'.$group.'_'.$id;
 515          }
 516      }
 517  
 518      function getCacheFile()
 519      {
 520          return $this->_file;
 521      }
 522  
 523      /**
 524      * Read the cache file and return the content
 525      *
 526      * @return string content of the cache file
 527      * @access private
 528      */
 529      function _read()
 530      {
 531          $fp = @fopen($this->_file, "rb");
 532          if ($this->_fileLocking) @flock($fp, LOCK_SH);
 533          if ($fp) {
 534              // because the filesize can be cached by PHP itself...
 535              clearstatcache();
 536              $length = @filesize($this->_file);
 537              $mqr = get_magic_quotes_runtime();
 538              set_magic_quotes_runtime(0);
 539              if ($this->_readControl) {
 540                  $hashControl = @fread($fp, 32);
 541                  $length = $length - 32;
 542              }
 543              $data = @fread($fp, $length);
 544              set_magic_quotes_runtime($mqr);
 545              if ($this->_fileLocking) @flock($fp, LOCK_UN);
 546              @fclose($fp);
 547              if ($this->_readControl) {
 548                  $hashData = $this->_hash($data, $this->_readControlType);
 549                  if ($hashData != $hashControl) {
 550                      @touch($this->_file, time() - 2*abs($this->_lifeTime));
 551                      return false;
 552                  }
 553              }
 554              return $data;
 555          }
 556          $this->raiseError('Cache_Lite : Unable to read cache !', -2);
 557          return false;
 558      }
 559  
 560      /**
 561      * Write the given data in the cache file
 562      *
 563      * @param string $data data to put in cache
 564      * @return boolean true if ok
 565      * @access private
 566      */
 567      function _write($data)
 568      {
 569          $fp = @fopen($this->_file, "wb");
 570          if ($fp) {
 571              if ($this->_fileLocking) @flock($fp, LOCK_EX);
 572              if ($this->_readControl) {
 573                  @fwrite($fp, $this->_hash($data, $this->_readControlType), 32);
 574              }
 575              $len = strlen($data);
 576              @fwrite($fp, $data, $len);
 577              if ($this->_fileLocking) @flock($fp, LOCK_UN);
 578              @fclose($fp);
 579              return true;
 580          }
 581          $this->raiseError('Cache_Lite : Unable to write cache !', -1);
 582          return false;
 583      }
 584  
 585      /**
 586      * Write the given data in the cache file and control it just after to avoid
 587      * corrupted cache entries
 588      *
 589      * @param string $data data to put in cache
 590      * @return boolean true if the test is ok
 591      * @access private
 592      */
 593      function _writeAndControl($data)
 594      {
 595          $this->_write($data);
 596          $dataRead = $this->_read($data);
 597          return ($dataRead==$data);
 598      }
 599  
 600      /**
 601      * Make a control key with the string containing datas
 602      *
 603      * @param string $data data
 604      * @param string $controlType type of control 'md5', 'crc32' or 'strlen'
 605      * @return string control key
 606      * @access private
 607      */
 608      function _hash($data, $controlType)
 609      {
 610          switch ($controlType) {
 611          case 'md5':
 612              return md5($data);
 613          case 'crc32':
 614              return sprintf('% 32d', crc32($data));
 615          case 'strlen':
 616              return sprintf('% 32d', strlen($data));
 617          default:
 618              $this->raiseError('Unknown controlType ! '.
 619              '(available values are only \'md5\', \'crc32\', \'strlen\')', -5);
 620          }
 621      }
 622  
 623  }
 624  
 625  ?>


Généré le : Sun Feb 25 21:07:04 2007 par Balluche grâce à PHPXref 0.7