[ Index ]
 

Code source de LifeType 1.2.4

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/class/cache/Cache_Lite/ -> Lite.php (source)

   1  <?php
   2  
   3  /**
   4  * \ingroup Cache
   5  *
   6  * Fast, light and safe Cache Class
   7  *
   8  * Cache_Lite is a fast, light and safe cache system. It's optimized
   9  * for file containers. It is fast and safe (because it uses file
  10  * locking and/or anti-corruption tests).
  11  *
  12  * There are some examples in the 'docs/examples' file
  13  * Technical choices are described in the 'docs/technical' file
  14  *
  15  * Memory Caching is from an original idea of
  16  * Mike BENOIT <ipso@snappymail.ca>
  17  *
  18  * Nota : A chinese documentation (thanks to RainX <china_1982@163.com>) is
  19  * available at :
  20  * http://rainx.phpmore.com/manual/cache_lite.html
  21  *
  22  * @package Cache_Lite
  23  * @category Caching
  24  * @version $Id: Lite.php,v 1.45 2006/06/03 08:10:33 fab Exp $
  25  * @author Fabien MARTY <fab@php.net>
  26  */
  27  
  28  define('CACHE_LITE_ERROR_RETURN', 1);
  29  define('CACHE_LITE_ERROR_DIE', 8);
  30  
  31  class Cache_Lite
  32  {
  33  
  34      // --- Private properties ---
  35  
  36      /**
  37      * Directory where to put the cache files
  38      * (make sure to add a trailing slash)
  39      *
  40      * @var string $_cacheDir
  41      */
  42      var $_cacheDir = '/tmp/';
  43  
  44      /**
  45      * Enable / disable caching
  46      *
  47      * (can be very usefull for the debug of cached scripts)
  48      *
  49      * @var boolean $_caching
  50      */
  51      var $_caching = true;
  52  
  53      /**
  54      * Cache lifetime (in seconds)
  55      *
  56      * If null, the cache is valid forever.
  57      *
  58      * @var int $_lifeTime
  59      */
  60      var $_lifeTime = 3600;
  61  
  62      /**
  63      * Enable / disable fileLocking
  64      *
  65      * (can avoid cache corruption under bad circumstances)
  66      *
  67      * @var boolean $_fileLocking
  68      */
  69      var $_fileLocking = true;
  70  
  71      /**
  72      * Timestamp of the last valid cache
  73      *
  74      * @var int $_refreshTime
  75      */
  76      var $_refreshTime;
  77  
  78      /**
  79      * File name (with path)
  80      *
  81      * @var string $_file
  82      */
  83      var $_file;
  84      
  85      /**
  86      * File name (without path)
  87      *
  88      * @var string $_fileName
  89      */
  90      var $_fileName;
  91  
  92      /**
  93      * Enable / disable write control (the cache is read just after writing to detect corrupt entries)
  94      *
  95      * Enable write control will lightly slow the cache writing but not the cache reading
  96      * Write control can detect some corrupt cache files but maybe it's not a perfect control
  97      *
  98      * @var boolean $_writeControl
  99      */
 100      var $_writeControl = true;
 101  
 102      /**
 103      * Enable / disable read control
 104      *
 105      * If enabled, a control key is embeded in cache file and this key is compared with the one
 106      * calculated after the reading.
 107      *
 108      * @var boolean $_writeControl
 109      */
 110      var $_readControl = true;
 111  
 112      /**
 113      * Type of read control (only if read control is enabled)
 114      *
 115      * Available values are :
 116      * 'md5' for a md5 hash control (best but slowest)
 117      * 'crc32' for a crc32 hash control (lightly less safe but faster, better choice)
 118      * 'strlen' for a length only test (fastest)
 119      *
 120      * @var boolean $_readControlType
 121      */
 122      var $_readControlType = 'crc32';
 123  
 124      /**
 125      * Pear error mode (when raiseError is called)
 126      *
 127      * (see PEAR doc)
 128      *
 129      * @see setToDebug()
 130      * @var int $_pearErrorMode
 131      */
 132      var $_pearErrorMode = CACHE_LITE_ERROR_RETURN;
 133      
 134      /**
 135      * Current cache id
 136      *
 137      * @var string $_id
 138      */
 139      var $_id;
 140  
 141      /**
 142      * Current cache group
 143      *
 144      * @var string $_group
 145      */
 146      var $_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      var $_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      var $_onlyMemoryCaching = false;
 164  
 165      /**
 166      * Memory caching array
 167      *
 168      * @var array $_memoryCachingArray
 169      */
 170      var $_memoryCachingArray = array();
 171  
 172      /**
 173      * Memory caching counter
 174      *
 175      * @var int $memoryCachingCounter
 176      */
 177      var $_memoryCachingCounter = 0;
 178  
 179      /**
 180      * Memory caching limit
 181      *
 182      * @var int $memoryCachingLimit
 183      */
 184      var $_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      var $_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      var $_automaticSerialization = false;
 207      
 208      /**
 209      * Disable / Tune the automatic cleaning process
 210      *
 211      * The automatic cleaning process destroy too old (for the given life time)
 212      * cache files when a new cache file is written.
 213      * 0               => no automatic cache cleaning
 214      * 1               => systematic cache cleaning
 215      * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write
 216      *
 217      * @var int $_automaticCleaning
 218      */
 219      var $_automaticCleaningFactor = 0;
 220      
 221      /**
 222      * Nested directory level
 223      *
 224      * Set the hashed directory structure level. 0 means "no hashed directory 
 225      * structure", 1 means "one level of directory", 2 means "two levels"... 
 226      * This option can speed up Cache_Lite only when you have many thousands of 
 227      * cache file. Only specific benchs can help you to choose the perfect value 
 228      * for you. Maybe, 1 or 2 is a good start.
 229      *
 230      * @var int $_hashedDirectoryLevel
 231      */
 232      var $_hashedDirectoryLevel = 0;
 233      
 234      /**
 235      * Umask for hashed directory structure
 236      *
 237      * @var int $_hashedDirectoryUmask
 238      */
 239      var $_hashedDirectoryUmask = 0700;
 240      
 241      /**
 242       * API break for error handling in CACHE_LITE_ERROR_RETURN mode
 243       * 
 244       * In CACHE_LITE_ERROR_RETURN mode, error handling was not good because
 245       * for example save() method always returned a boolean (a PEAR_Error object
 246       * would be better in CACHE_LITE_ERROR_RETURN mode). To correct this without
 247       * breaking the API, this option (false by default) can change this handling.
 248       * 
 249       * @var boolean
 250       */
 251      var $_errorHandlingAPIBreak = false;
 252      
 253      // --- Public methods ---
 254  
 255      /**
 256      * Constructor
 257      *
 258      * $options is an assoc. Available options are :
 259      * $options = array(
 260      *     'cacheDir' => directory where to put the cache files (string),
 261      *     'caching' => enable / disable caching (boolean),
 262      *     'lifeTime' => cache lifetime in seconds (int),
 263      *     'fileLocking' => enable / disable fileLocking (boolean),
 264      *     'writeControl' => enable / disable write control (boolean),
 265      *     'readControl' => enable / disable read control (boolean),
 266      *     'readControlType' => type of read control 'crc32', 'md5', 'strlen' (string),
 267      *     'pearErrorMode' => pear error mode (when raiseError is called) (cf PEAR doc) (int),
 268      *     'memoryCaching' => enable / disable memory caching (boolean),
 269      *     'onlyMemoryCaching' => enable / disable only memory caching (boolean),
 270      *     'memoryCachingLimit' => max nbr of records to store into memory caching (int),
 271      *     'fileNameProtection' => enable / disable automatic file name protection (boolean),
 272      *     'automaticSerialization' => enable / disable automatic serialization (boolean),
 273      *     'automaticCleaningFactor' => distable / tune automatic cleaning process (int),
 274      *     'hashedDirectoryLevel' => level of the hashed directory system (int),
 275      *     'hashedDirectoryUmask' => umask for hashed directory structure (int),
 276      *     'errorHandlingAPIBreak' => API break for better error handling ? (boolean)
 277      * );
 278      *
 279      * @param array $options options
 280      * @access public
 281      */
 282      function Cache_Lite($options = array(NULL))
 283      {
 284          foreach($options as $key => $value) {
 285              $this->setOption($key, $value);
 286          }
 287      }
 288      
 289      /**
 290      * Generic way to set a Cache_Lite option
 291      *
 292      * see Cache_Lite constructor for available options
 293      *
 294      * @var string $name name of the option
 295      * @var mixed $value value of the option
 296      * @access public
 297      */
 298      function setOption($name, $value) 
 299      {
 300          $availableOptions = array('errorHandlingAPIBreak', 'hashedDirectoryUmask', 'hashedDirectoryLevel', 'automaticCleaningFactor', 'automaticSerialization', 'fileNameProtection', 'memoryCaching', 'onlyMemoryCaching', 'memoryCachingLimit', 'cacheDir', 'caching', 'lifeTime', 'fileLocking', 'writeControl', 'readControl', 'readControlType', 'pearErrorMode');
 301          if (in_array($name, $availableOptions)) {
 302              $property = '_'.$name;
 303              $this->$property = $value;
 304          }
 305      }
 306      
 307      /**
 308      * Test if a cache is available and (if yes) return it
 309      *
 310      * @param string $id cache id
 311      * @param string $group name of the cache group
 312      * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
 313      * @return string data of the cache (else : false)
 314      * @access public
 315      */
 316      function get($id, $group = 'default', $doNotTestCacheValidity = false)
 317      {
 318          $this->_id = $id;
 319          $this->_group = $group;
 320          $data = false;
 321          if ($this->_caching) {
 322              $this->_setRefreshTime();
 323              $this->_setFileName($id, $group);
 324              clearstatcache();
 325              if ($this->_memoryCaching) {
 326                  if (isset($this->_memoryCachingArray[$this->_file])) {
 327                      if ($this->_automaticSerialization) {
 328                          return unserialize($this->_memoryCachingArray[$this->_file]);
 329                      }
 330                      return $this->_memoryCachingArray[$this->_file];
 331                  }
 332                  if ($this->_onlyMemoryCaching) {
 333                      return false;
 334                  }                
 335              }
 336              if (($doNotTestCacheValidity) || (is_null($this->_refreshTime))) {
 337                  if (file_exists($this->_file)) {
 338                      $data = $this->_read();
 339                  }
 340              } else {
 341                  if ((file_exists($this->_file)) && (@filemtime($this->_file) > $this->_refreshTime)) {
 342                      $data = $this->_read();
 343                  }
 344              }
 345              if (($data) and ($this->_memoryCaching)) {
 346                  $this->_memoryCacheAdd($data);
 347              }
 348              if (($this->_automaticSerialization) and (is_string($data))) {
 349                  $data = unserialize($data);
 350              }
 351              return $data;
 352          }
 353          return false;
 354      }
 355      
 356      /**
 357      * Save some data in a cache file
 358      *
 359      * @param string $data data to put in cache (can be another type than strings if automaticSerialization is on)
 360      * @param string $id cache id
 361      * @param string $group name of the cache group
 362      * @return boolean true if no problem (else : false or a PEAR_Error object)
 363      * @access public
 364      */
 365      function save($data, $id = NULL, $group = 'default')
 366      {
 367          if ($this->_caching) {
 368              if ($this->_automaticSerialization) {
 369                  $data = serialize($data);
 370              }
 371              if (isset($id)) {
 372                  $this->_setFileName($id, $group);
 373              }
 374              if ($this->_memoryCaching) {
 375                  $this->_memoryCacheAdd($data);
 376                  if ($this->_onlyMemoryCaching) {
 377                      return true;
 378                  }
 379              }
 380              if ($this->_automaticCleaningFactor>0) {
 381                  $rand = rand(1, $this->_automaticCleaningFactor);
 382                  if ($rand==1) {
 383                      $this->clean(false, 'old');
 384                  }
 385              }
 386              if ($this->_writeControl) {
 387                  $res = $this->_writeAndControl($data);
 388                  if (is_bool($res)) {
 389                      if ($res) {
 390                          return true;  
 391                      }
 392                      // if $res if false, we need to invalidate the cache
 393                      @touch($this->_file, time() - 2*abs($this->_lifeTime));
 394                      return false;
 395                  }            
 396              } else {
 397                  $res = $this->_write($data);
 398              }
 399              if (is_object($res)) {
 400                  // $res is a PEAR_Error object 
 401                  if (!($this->_errorHandlingAPIBreak)) {   
 402                      return false; // we return false (old API)
 403                  }
 404              }
 405              return $res;
 406          }
 407          return false;
 408      }
 409  
 410      /**
 411      * Remove a cache file
 412      *
 413      * @param string $id cache id
 414      * @param string $group name of the cache group
 415      * @return boolean true if no problem
 416      * @access public
 417      */
 418      function remove($id, $group = 'default')
 419      {
 420          $this->_setFileName($id, $group);
 421          if ($this->_memoryCaching) {
 422              if (isset($this->_memoryCachingArray[$this->_file])) {
 423                  unset($this->_memoryCachingArray[$this->_file]);
 424                  $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1;
 425              }
 426              if ($this->_onlyMemoryCaching) {
 427                  return true;
 428              }
 429          }
 430          return $this->_unlink($this->_file);
 431      }
 432  
 433      /**
 434      * Clean the cache
 435      *
 436      * if no group is specified all cache files will be destroyed
 437      * else only cache files of the specified group will be destroyed
 438      *
 439      * @param string $group name of the cache group
 440      * @param string $mode flush cache mode : 'old', 'ingroup', 'notingroup', 
 441      *                                        'callback_myFunction'
 442      * @return boolean true if no problem
 443      * @access public
 444      */
 445      function clean($group = false, $mode = 'ingroup')
 446      {
 447          return $this->_cleanDir($this->_cacheDir, $group, $mode);
 448      }
 449         
 450      /**
 451      * Set to debug mode
 452      *
 453      * When an error is found, the script will stop and the message will be displayed
 454      * (in debug mode only). 
 455      *
 456      * @access public
 457      */
 458      function setToDebug()
 459      {
 460          $this->setOption('pearErrorMode', CACHE_LITE_ERROR_DIE);
 461      }
 462  
 463      /**
 464      * Set a new life time
 465      *
 466      * @param int $newLifeTime new life time (in seconds)
 467      * @access public
 468      */
 469      function setLifeTime($newLifeTime)
 470      {
 471          $this->_lifeTime = $newLifeTime;
 472          $this->_setRefreshTime();
 473      }
 474  
 475      /**
 476      * Save the state of the caching memory array into a cache file cache
 477      *
 478      * @param string $id cache id
 479      * @param string $group name of the cache group
 480      * @access public
 481      */
 482      function saveMemoryCachingState($id, $group = 'default')
 483      {
 484          if ($this->_caching) {
 485              $array = array(
 486                  'counter' => $this->_memoryCachingCounter,
 487                  'array' => $this->_memoryCachingState
 488              );
 489              $data = serialize($array);
 490              $this->save($data, $id, $group);
 491          }
 492      }
 493  
 494      /**
 495      * Load the state of the caching memory array from a given cache file cache
 496      *
 497      * @param string $id cache id
 498      * @param string $group name of the cache group
 499      * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
 500      * @access public
 501      */
 502      function getMemoryCachingState($id, $group = 'default', $doNotTestCacheValidity = false)
 503      {
 504          if ($this->_caching) {
 505              if ($data = $this->get($id, $group, $doNotTestCacheValidity)) {
 506                  $array = unserialize($data);
 507                  $this->_memoryCachingCounter = $array['counter'];
 508                  $this->_memoryCachingArray = $array['array'];
 509              }
 510          }
 511      }
 512      
 513      /**
 514      * Return the cache last modification time
 515      *
 516      * BE CAREFUL : THIS METHOD IS FOR HACKING ONLY !
 517      *
 518      * @return int last modification time
 519      */
 520      function lastModified() 
 521      {
 522          return @filemtime($this->_file);
 523      }
 524      
 525      /**
 526      * Trigger a PEAR error
 527      *
 528      * To improve performances, the PEAR.php file is included dynamically.
 529      * The file is so included only when an error is triggered. So, in most
 530      * cases, the file isn't included and perfs are much better.
 531      *
 532      * @param string $msg error message
 533      * @param int $code error code
 534      * @access public
 535      */
 536      function raiseError($msg, $code)
 537      {
 538          lt_include( PLOG_CLASS_PATH."class/logger/loggermanager.class.php" );    
 539          $log =& LoggerManager::getLogger();
 540          $log->error($msg, LOGGER_PRIO_ERROR);
 541      }
 542      
 543      /**
 544       * Extend the life of a valid cache file
 545       * 
 546       * see http://pear.php.net/bugs/bug.php?id=6681
 547       * 
 548       * @access public
 549       */
 550      function extendLife()
 551      {
 552          @touch($this->_file);
 553      }
 554      
 555      // --- Private methods ---
 556      
 557      /**
 558      * Compute & set the refresh time
 559      *
 560      * @access private
 561      */
 562      function _setRefreshTime() 
 563      {
 564          if (is_null($this->_lifeTime)) {
 565              $this->_refreshTime = null;
 566          } else {
 567              $this->_refreshTime = time() - $this->_lifeTime;
 568          }
 569      }
 570      
 571      /**
 572      * Remove a file
 573      * 
 574      * @param string $file complete file path and name
 575      * @return boolean true if no problem
 576      * @access private
 577      */
 578      function _unlink($file)
 579      {
 580          if (file_exists($file) && !@unlink($file)) {
 581              return $this->raiseError('Cache_Lite : Unable to remove cache !', -3);
 582          }
 583          return true;        
 584      }
 585  
 586      /**
 587      * Recursive function for cleaning cache file in the given directory
 588      *
 589      * @param string $dir directory complete path (with a trailing slash)
 590      * @param string $group name of the cache group
 591      * @param string $mode flush cache mode : 'old', 'ingroup', 'notingroup',
 592                                               'callback_myFunction'
 593      * @return boolean true if no problem
 594      * @access private
 595      */
 596      function _cleanDir($dir, $group = false, $mode = 'ingroup')     
 597      {
 598          if ($this->_fileNameProtection) {
 599              $motif = ($group) ? 'cache_'.md5($group).'_' : 'cache_';
 600          } else {
 601              $motif = ($group) ? 'cache_'.$group.'_' : 'cache_';
 602          }
 603          if ($this->_memoryCaching) {
 604              while (list($key, ) = each($this->_memoryCachingArray)) {
 605                  if (strpos($key, $motif, 0)) {
 606                      unset($this->_memoryCachingArray[$key]);
 607                      $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1;
 608                  }
 609              }
 610              if ($this->_onlyMemoryCaching) {
 611                  return true;
 612              }
 613          }
 614          if (!($dh = opendir($dir))) {
 615              return $this->raiseError('Cache_Lite : Unable to open cache directory !', -4);
 616          }
 617          $result = true;
 618          while ($file = readdir($dh)) {
 619              if (($file != '.') && ($file != '..')) {
 620                  if (substr($file, 0, 6)=='cache_') {
 621                      $file2 = $dir . $file;
 622                      if (is_file($file2)) {
 623                          switch (substr($mode, 0, 9)) {
 624                              case 'old':
 625                                  // files older than lifeTime get deleted from cache
 626                                  if (!is_null($this->_lifeTime)) {
 627                                      if ((mktime() - @filemtime($file2)) > $this->_lifeTime) {
 628                                          $result = ($result and ($this->_unlink($file2)));
 629                                      }
 630                                  }
 631                                  break;
 632                              case 'notingroup':
 633                                  if (!strpos($file2, $motif, 0)) {
 634                                      $result = ($result and ($this->_unlink($file2)));
 635                                  }
 636                                  break;
 637                              case 'callback_':
 638                                  $func = substr($mode, 9, strlen($mode) - 9);
 639                                  if ($func($file2, $group)) {
 640                                      $result = ($result and ($this->_unlink($file2)));
 641                                  }
 642                                  break;
 643                              case 'ingroup':
 644                              default:
 645                                  if (strpos($file2, $motif, 0)) {
 646                                      $result = ($result and ($this->_unlink($file2)));
 647                                  }
 648                                  break;
 649                          }
 650                      }
 651                      if ((is_dir($file2)) and ($this->_hashedDirectoryLevel>0)) {
 652                          $result = ($result and ($this->_cleanDir($file2 . '/', $group, $mode)));
 653                      }
 654                  }
 655              }
 656          }
 657          return $result;
 658      }
 659        
 660      /**
 661      * Add some date in the memory caching array
 662      *
 663      * @param string $data data to cache
 664      * @access private
 665      */
 666      function _memoryCacheAdd($data)
 667      {
 668          $this->_memoryCachingArray[$this->_file] = $data;
 669          if ($this->_memoryCachingCounter >= $this->_memoryCachingLimit) {
 670              list($key, ) = each($this->_memoryCachingArray);
 671              unset($this->_memoryCachingArray[$key]);
 672          } else {
 673              $this->_memoryCachingCounter = $this->_memoryCachingCounter + 1;
 674          }
 675      }
 676  
 677      /**
 678      * Make a file name (with path)
 679      *
 680      * @param string $id cache id
 681      * @param string $group name of the group
 682      * @access private
 683      */
 684      function _setFileName($id, $group)
 685      {
 686          
 687          if ($this->_fileNameProtection) {
 688              $suffix = 'cache_'.md5($group).'_'.md5($id);
 689          } else {
 690              $suffix = 'cache_'.$group.'_'.$id;
 691          }
 692          $root = $this->_cacheDir;
 693          if ($this->_hashedDirectoryLevel>0) {
 694              $hash = md5($suffix);
 695              for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) {
 696                  $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
 697              }   
 698          }
 699          $this->_fileName = $suffix;
 700          $this->_file = $root.$suffix;
 701      }
 702      
 703      /**
 704      * Read the cache file and return the content
 705      *
 706      * @return string content of the cache file (else : false or a PEAR_Error object)
 707      * @access private
 708      */
 709      function _read()
 710      {
 711          $fp = @fopen($this->_file, "rb");
 712          if ($this->_fileLocking) @flock($fp, LOCK_SH);
 713          if ($fp) {
 714              clearstatcache();
 715              $length = @filesize($this->_file);
 716              $mqr = get_magic_quotes_runtime();
 717              set_magic_quotes_runtime(0);
 718              if ($this->_readControl) {
 719                  $hashControl = @fread($fp, 32);
 720                  $length = $length - 32;
 721              } 
 722              if ($length) {
 723                  $data = @fread($fp, $length);
 724              } else {
 725                  $data = '';
 726              }
 727              set_magic_quotes_runtime($mqr);
 728              if ($this->_fileLocking) @flock($fp, LOCK_UN);
 729              @fclose($fp);
 730              if ($this->_readControl) {
 731                  $hashData = $this->_hash($data, $this->_readControlType);
 732                  if ($hashData != $hashControl) {
 733                      if (!(is_null($this->_lifeTime))) {
 734                          @touch($this->_file, time() - 2*abs($this->_lifeTime)); 
 735                      } else {
 736                          @unlink($this->_file);
 737                      }
 738                      return false;
 739                  }
 740              }
 741              return $data;
 742          }
 743          return $this->raiseError('Cache_Lite : Unable to read cache !', -2); 
 744      }
 745      
 746      /**
 747      * Write the given data in the cache file
 748      *
 749      * @param string $data data to put in cache
 750      * @return boolean true if ok (a PEAR_Error object else)
 751      * @access private
 752      */
 753      function _write($data)
 754      {
 755          if (!is_dir(dirname($this->_file)) && $this->_hashedDirectoryLevel > 0) {
 756              $hash = md5($this->_fileName);
 757              $root = $this->_cacheDir;
 758              for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) {
 759                  $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
 760                  if (!(@is_dir($root))) {
 761                      @mkdir($root, $this->_hashedDirectoryUmask);
 762                  }
 763              }
 764          }
 765          $fp = @fopen($this->_file, "wb");
 766          if ($fp) {
 767              if ($this->_fileLocking) @flock($fp, LOCK_EX);
 768              if ($this->_readControl) {
 769                  @fwrite($fp, $this->_hash($data, $this->_readControlType), 32);
 770              }
 771              $len = strlen($data);
 772              @fwrite($fp, $data, $len);
 773              if ($this->_fileLocking) @flock($fp, LOCK_UN);
 774              @fclose($fp);
 775              return true;
 776          }      
 777          return $this->raiseError('Cache_Lite : Unable to write cache file : '.$this->_file, -1);
 778      }
 779         
 780      /**
 781      * Write the given data in the cache file and control it just after to avoir corrupted cache entries
 782      *
 783      * @param string $data data to put in cache
 784      * @return boolean true if the test is ok (else : false or a PEAR_Error object)
 785      * @access private
 786      */
 787      function _writeAndControl($data)
 788      {
 789          $result = $this->_write($data);
 790          if (is_object($result)) {
 791              return $result; # We return the PEAR_Error object
 792          }
 793          $dataRead = $this->_read();
 794          if (is_object($dataRead)) {
 795              return $result; # We return the PEAR_Error object
 796          }
 797          if ((is_bool($dataRead)) && (!$dataRead)) {
 798              return false; 
 799          }
 800          return ($dataRead==$data);
 801      }
 802      
 803      /**
 804      * Make a control key with the string containing datas
 805      *
 806      * @param string $data data
 807      * @param string $controlType type of control 'md5', 'crc32' or 'strlen'
 808      * @return string control key
 809      * @access private
 810      */
 811      function _hash($data, $controlType)
 812      {
 813          switch ($controlType) {
 814          case 'md5':
 815              return md5($data);
 816          case 'crc32':
 817              return sprintf('% 32d', crc32($data));
 818          case 'strlen':
 819              return sprintf('% 32d', strlen($data));
 820          default:
 821              return $this->raiseError('Unknown controlType ! (available values are only \'md5\', \'crc32\', \'strlen\')', -5);
 822          }
 823      }
 824      
 825  } 
 826  
 827  ?>


Généré le : Mon Nov 26 21:04:15 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics