Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2017
45
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.89 KB | None | 0 0
  1. <?php
  2.  
  3. /*
  4.  * Usage:
  5.  *
  6.  * function getABunchOfData(
  7.  *    $fileCache = new FileCacheComponent();
  8.  *
  9.  *    $cacheKey = 'anIdentifierForThisBunchOfData';
  10.  *
  11.  *    if (false==($aBunchOfData=$fileCache->load($cacheKey))) {
  12.  *       $aBunchOfData = .... WHATEVER, FETCH FROM A DB, GRAB FROM AN API, WHATEVER
  13.  *       $fileCache->save($cacheKey,$aBunchOfData,60*60);
  14.  *    }
  15.  *    return $aBunchOfData;
  16.  * }
  17.  *
  18.  *
  19.  *
  20.  * The bits you need to worry about;
  21.  *
  22.  * Set the $path variable in the class to where you want the cache files to live
  23.  * The should automatically keep themselves in check, deleting old ones as it goes along
  24.  * so you shouldnt really need to worry about housekeeping
  25.  *
  26.  * You can either do:
  27.  *    new FileCacheComponent()
  28.  * or
  29.  *    new FileCacheComponent('CacheFilesWillBePrefixedWithThisString')
  30.  *
  31.  *
  32.  *
  33.  * To save something to the cache:
  34.  *
  35.  * ->save('aStringIdentifier',$yourData,$secondsToKeepItValid);
  36.  *
  37.  * To retreive from the cache
  38.  *
  39.  * ->load('aStringIdentifier')
  40.  *  this will return false if nothing found or if the data in the cache has expired
  41.  *
  42.  * To delete something from the cache
  43.  *
  44.  * ->clear('aStringIdentifier');
  45.  *
  46.  * To delete everything from the cache
  47.  *
  48.  * ->clearAll();
  49.  *
  50.  */
  51.  
  52. class FileCacheComponent  {
  53.    
  54.    var $expiry = 5;
  55.    var $path = '/tmp';
  56.    var $referenceTime = 0;
  57.    var $prefix = '';
  58.    
  59.    public function __construct($prefix = 'YourAppName') {
  60.       // Set a reference time to be used throughout this instantiation
  61.       $this->referenceTime = time();
  62.       $this->prefix = $prefix;
  63.       // Check for stale cache files ~1 in every 5 times this class is instantiated
  64.       if (rand(0,100)<20) {
  65.          $this->deleteStaleCacheFiles();
  66.       }
  67.    }
  68.    
  69.    public function load($key) {
  70.       // Check if there is a valid cache file for this key, if so retreive the file, deserialize it and return the result
  71.       if (!$this->isKeyValidInCache($key)) {
  72.          return false;  
  73.       }
  74.       return unserialize(file_get_contents($this->getFilenameForKey($key)));
  75.    }
  76.    
  77.    public function save($key,$data,$expiry=300) {
  78.       // Generate a filename for this key/expiry time, serialize the data and save to file      
  79.       $filename = $this->getFilenameForKey($key,time()+$expiry);
  80.       $data = serialize($data);
  81.       return file_put_contents($filename, $data);
  82.    }
  83.    
  84.    public function clear($key) {
  85.       $filename = $this->getFilenameForKey($key);
  86.       return $this->deleteStaleCacheFiles($filename,true);
  87.    }
  88.    
  89.    public function clearAll() {
  90.       return $this->deleteStaleCacheFiles(null,true);
  91.    }
  92.    
  93.    private function isKeyValidInCache($key) {
  94.       $filename = $this->getFilenameForKey($key);
  95.       if (!$filename) return false; // Invalid if a filename couldn't be determined
  96.       if (!file_exists($filename)) return false;  // Invalid if file doesn't exist
  97.       $expiryTime = $this->getExpiryTimeFromFilename($filename);
  98.       if (!$expiryTime) return false; // Invalid if an expiry time for the file couldnt be determined
  99.       if ($expiryTime < $this->referenceTime) return false; // Invalid if expiry time < referenceTime
  100.       return true; // Passed all the checks, cache file appears to be valid
  101.    }
  102.    
  103.    private function getFilenameForKey($key,$expiryTime=null) {
  104.       if ($expiryTime!=null) {
  105.          // Expiry time was passed as a parameter, so we just need to construct the filename format
  106.          $hash = md5(serialize($key));
  107.          $paddedExpiryTime = str_pad($expiryTime,15,'0',STR_PAD_LEFT);
  108.          $filename = "{$this->path}/{$this->prefix}.{$hash}.{$paddedExpiryTime}.cache";
  109.          return $filename;
  110.       } else {
  111.          // No expiry time was passed, so we need to find the newest file for this cache key
  112.          return $this->findLatestFilenameForKey($key);
  113.       }
  114.    }
  115.    
  116.    private function findLatestFilenameForKey($key) {
  117.       $hash = md5(serialize($key));
  118.       // Find all cache files for this cache key
  119.       $pattern = "{$this->path}/{$this->prefix}.{$hash}.*.cache";
  120.       $glob = glob($pattern);
  121.       if (count($glob)==0) {
  122.          // No files found
  123.          return false;  
  124.       } else {
  125.          // We want to return the last filename returned (ie, the newest file - because filenames are sorted, and newest file will have
  126.          // the greatest value for the timestamp portion
  127.          $return = array_pop($glob);
  128.          if (count($glob)>0) {
  129.             // If there was more than just the one filename returned for this cache key, we can delete all the other files - we're just interested
  130.             // in the newset file for this key
  131.             $this->deleteStaleCacheFiles($glob);
  132.          }
  133.       }
  134.       return $return;
  135.    }
  136.    
  137.    
  138.    public function deleteStaleCacheFiles($files = null,$indiscriminate=false) {
  139.       $filesDeleted = 0;
  140.       if ($files != null) {
  141.          // A list of files to delete has been passed in
  142.          if (!is_array($files)) $files = array($files);
  143.          foreach ($files AS $file) {
  144.             unlink($file);
  145.             $filesDeleted++;
  146.          }  
  147.       } else {
  148.          // No list of filenames supplied, so lets just find ALL cache files and check their expiry times
  149.          $pattern = "{$this->path}/{$this->prefix}.*.cache";
  150.          $glob = glob($pattern);
  151.          foreach($glob AS $filename) {
  152.             if ($indiscriminate || $this->getExpiryTimeFromFilename($filename) < $this->referenceTime) {
  153.                unlink($filename);
  154.                $filesDeleted++;
  155.             }
  156.          }
  157.       }
  158.       return $filesDeleted;
  159.    }
  160.    
  161.    private function getExpiryTimeFromFilename($filename) {
  162.       // The expiry time is the number immediately before the .cache extension of the filename
  163.       $doesMatch = preg_match('/([0-9]{15})\.cache$/',$filename,$matches);
  164.       if (!$doesMatch) return false;
  165.       return (int)$matches[1];
  166.    }
  167.  
  168. }
  169.  
  170.  
  171. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement