Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /*
- * Usage:
- *
- * function getABunchOfData(
- * $fileCache = new FileCacheComponent();
- *
- * $cacheKey = 'anIdentifierForThisBunchOfData';
- *
- * if (false==($aBunchOfData=$fileCache->load($cacheKey))) {
- * $aBunchOfData = .... WHATEVER, FETCH FROM A DB, GRAB FROM AN API, WHATEVER
- * $fileCache->save($cacheKey,$aBunchOfData,60*60);
- * }
- * return $aBunchOfData;
- * }
- *
- *
- *
- * The bits you need to worry about;
- *
- * Set the $path variable in the class to where you want the cache files to live
- * The should automatically keep themselves in check, deleting old ones as it goes along
- * so you shouldnt really need to worry about housekeeping
- *
- * You can either do:
- * new FileCacheComponent()
- * or
- * new FileCacheComponent('CacheFilesWillBePrefixedWithThisString')
- *
- *
- *
- * To save something to the cache:
- *
- * ->save('aStringIdentifier',$yourData,$secondsToKeepItValid);
- *
- * To retreive from the cache
- *
- * ->load('aStringIdentifier')
- * this will return false if nothing found or if the data in the cache has expired
- *
- * To delete something from the cache
- *
- * ->clear('aStringIdentifier');
- *
- * To delete everything from the cache
- *
- * ->clearAll();
- *
- */
- class FileCacheComponent {
- var $expiry = 5;
- var $path = '/tmp';
- var $referenceTime = 0;
- var $prefix = '';
- public function __construct($prefix = 'YourAppName') {
- // Set a reference time to be used throughout this instantiation
- $this->referenceTime = time();
- $this->prefix = $prefix;
- // Check for stale cache files ~1 in every 5 times this class is instantiated
- if (rand(0,100)<20) {
- $this->deleteStaleCacheFiles();
- }
- }
- public function load($key) {
- // Check if there is a valid cache file for this key, if so retreive the file, deserialize it and return the result
- if (!$this->isKeyValidInCache($key)) {
- return false;
- }
- return unserialize(file_get_contents($this->getFilenameForKey($key)));
- }
- public function save($key,$data,$expiry=300) {
- // Generate a filename for this key/expiry time, serialize the data and save to file
- $filename = $this->getFilenameForKey($key,time()+$expiry);
- $data = serialize($data);
- return file_put_contents($filename, $data);
- }
- public function clear($key) {
- $filename = $this->getFilenameForKey($key);
- return $this->deleteStaleCacheFiles($filename,true);
- }
- public function clearAll() {
- return $this->deleteStaleCacheFiles(null,true);
- }
- private function isKeyValidInCache($key) {
- $filename = $this->getFilenameForKey($key);
- if (!$filename) return false; // Invalid if a filename couldn't be determined
- if (!file_exists($filename)) return false; // Invalid if file doesn't exist
- $expiryTime = $this->getExpiryTimeFromFilename($filename);
- if (!$expiryTime) return false; // Invalid if an expiry time for the file couldnt be determined
- if ($expiryTime < $this->referenceTime) return false; // Invalid if expiry time < referenceTime
- return true; // Passed all the checks, cache file appears to be valid
- }
- private function getFilenameForKey($key,$expiryTime=null) {
- if ($expiryTime!=null) {
- // Expiry time was passed as a parameter, so we just need to construct the filename format
- $hash = md5(serialize($key));
- $paddedExpiryTime = str_pad($expiryTime,15,'0',STR_PAD_LEFT);
- $filename = "{$this->path}/{$this->prefix}.{$hash}.{$paddedExpiryTime}.cache";
- return $filename;
- } else {
- // No expiry time was passed, so we need to find the newest file for this cache key
- return $this->findLatestFilenameForKey($key);
- }
- }
- private function findLatestFilenameForKey($key) {
- $hash = md5(serialize($key));
- // Find all cache files for this cache key
- $pattern = "{$this->path}/{$this->prefix}.{$hash}.*.cache";
- $glob = glob($pattern);
- if (count($glob)==0) {
- // No files found
- return false;
- } else {
- // We want to return the last filename returned (ie, the newest file - because filenames are sorted, and newest file will have
- // the greatest value for the timestamp portion
- $return = array_pop($glob);
- if (count($glob)>0) {
- // 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
- // in the newset file for this key
- $this->deleteStaleCacheFiles($glob);
- }
- }
- return $return;
- }
- public function deleteStaleCacheFiles($files = null,$indiscriminate=false) {
- $filesDeleted = 0;
- if ($files != null) {
- // A list of files to delete has been passed in
- if (!is_array($files)) $files = array($files);
- foreach ($files AS $file) {
- unlink($file);
- $filesDeleted++;
- }
- } else {
- // No list of filenames supplied, so lets just find ALL cache files and check their expiry times
- $pattern = "{$this->path}/{$this->prefix}.*.cache";
- $glob = glob($pattern);
- foreach($glob AS $filename) {
- if ($indiscriminate || $this->getExpiryTimeFromFilename($filename) < $this->referenceTime) {
- unlink($filename);
- $filesDeleted++;
- }
- }
- }
- return $filesDeleted;
- }
- private function getExpiryTimeFromFilename($filename) {
- // The expiry time is the number immediately before the .cache extension of the filename
- $doesMatch = preg_match('/([0-9]{15})\.cache$/',$filename,$matches);
- if (!$doesMatch) return false;
- return (int)$matches[1];
- }
- }
- ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement