Copy Code code as follows:
Class Cacheexception extends Exception {}
/**
* Cache abstract Class
*/
Abstract class Cache_abstract {
/**
* Read Cache variable
*
* @param string $key cache subscript
* @return Mixed
*/
Abstract public Function fetch ($KEY);
/**
* Cache Variables
*
* @param string $key cache variable Subscript
* @param string $value The value of the cached variable
* @return BOOL
*/
Abstract Public function Store ($key, $value);
/**
* Delete Cache variable
*
* @param string $key cache subscript
* @return Cache_abstract
*/
Abstract Public Function Delete ($key);
/**
* Clear (delete) except for all caches
*
* @return Cache_abstract
*/
Abstract public Function clear ();
/**
* Lock Cache variable
*
* @param string $key cache subscript
* @return Cache_abstract
*/
Abstract Public Function lock ($key);
/**
* Cache variable Unlock
*
* @param string $key cache subscript
* @return Cache_abstract
*/
Abstract public Function unlock ($key);
/**
* Get the cache variable locked
*
* @param string $key cache subscript
* @return BOOL
*/
Abstract public Function islocked ($key);
/**
* Make sure it's not locked
* Up to do $tries sleep waiting to unlock, timeout is skipped and unlocked
*
* @param string $key cache subscript
*/
Public Function Checklock ($key) {
if (! $this->islocked ($key)) {
return $this;
}
$tries = 10;
$count = 0;
do {
Usleep (200);
$count + +;
while ($count <= $tries && $this->islocked ($key)); Do up to 10 times sleep wait for unlock, timeout to skip and unlock
$this->islocked ($key) && $this->unlock ($key);
return $this;
}
}
/**
* APC Extended Cache implementation
*
*
* @category Mjie
* @package Cache
* @author Water Mengchun
* @copyright Copyright (c) 2008-<cmpan (at) qq.com>
* @license New BSD License
* @version $Id: cache/apc.php version number 2010-04-18 23:02 Cmpan $
*/
Class Cache_apc extends Cache_abstract {
protected $_prefix = ' cache.mjie.net ';
Public Function __construct () {
if (!function_exists (' Apc_cache_info ')) {
throw new Cacheexception (' APC extension didn\ ' t installed ');
}
}
/**
* Save Cache variables
*
* @param string $key
* @param mixed $value
* @return BOOL
*/
Public function Store ($key, $value) {
Return Apc_store ($this->_storagekey ($key), $value);
}
/**
* Read Cache
*
* @param string $key
* @return Mixed
*/
Public function Fetch ($key) {
Return Apc_fetch ($this->_storagekey ($key));
}
/**
* Clear Cache
*
* @return CACHE_APC
*/
Public Function Clear () {
Apc_clear_cache ();
return $this;
}
/**
* Delete Cache unit
*
* @return CACHE_APC
*/
Public Function Delete ($key) {
Apc_delete ($this->_storagekey ($key));
return $this;
}
/**
* Whether the cache unit is locked
*
* @param string $key
* @return BOOL
*/
Public Function islocked ($key) {
if (Apc_fetch ($this->_storagekey ($key). '. Lock ') = = = False) {
return false;
}
return true;
}
/**
* Lock Cache Unit
*
* @param string $key
* @return CACHE_APC
*/
Public function Lock ($key) {
Apc_store ($this->_storagekey ($key). '. Lock ', ', 5 ';
return $this;
}
/**
* Buffer Unit Unlock
*
* @param string $key
* @return CACHE_APC
*/
Public function Unlock ($key) {
Apc_delete ($this->_storagekey ($key). '. Lock ');
return $this;
}
/**
* Full Cache Name
*
* @param string $key
* @return String
*/
Private Function _storagekey ($key) {
Return $this->_prefix. '_' . $key;
}
}
/**
* File Cache implementation
*
*
* @category Mjie
* @package Cache
* @author Water Mengchun
* @copyright Copyright (c) 2008-<cmpan (at) qq.com>
* @license New BSD License
* @version $Id: cache/file.php version number 2010-04-18 16:46 Cmpan $
*/
Class Cache_file extends Cache_abstract {
Protected $_cachesdir = ' cache ';
Public Function __construct () {
if (defined (' Data_dir ')) {
$this->_setcachedir (Data_dir. '/cache ');
}
}
/**
* Get cached files
*
* @param string $key
* @return String
*/
protected function _getcachefile ($key) {
Return $this->_cachesdir. '/' . substr ($key, 0, 2). '/' . $key. '. php ';
}
/**
* Read Cache variables
* To prevent information leakage, cache file format for PHP files, and to "<?php exit;? > "Start
*
* @param string $key cache subscript
* @return Mixed
*/
Public function Fetch ($key) {
$cacheFile = Self::_getcachefile ($key);
if (file_exists ($cacheFile) && is_readable ($cacheFile)) {
Return Unserialize (@file_get_contents ($cacheFile, False, NULL, 13));
}
return false;
}
/**
* Cache Variables
* To prevent information leakage, cache file format for PHP files, and to "<?php exit;? > "Start
*
* @param string $key cache variable Subscript
* @param string $value The value of the cached variable
* @return BOOL
*/
Public function Store ($key, $value) {
$cacheFile = Self::_getcachefile ($key);
$cacheDir = DirName ($cacheFile);
if (!is_dir ($cacheDir)) {
if (mkdir ($cacheDir "target=" _blank ">! @mkdir ($cacheDir, 0755, True)) {
throw new Cacheexception ("Could not make cache directory");
}
}
Return @file_put_contents ($cacheFile, ' <?php exit;? > '. Serialize ($value));
}
/**
* Delete Cache variable
*
* @param string $key cache subscript
* @return Cache_file
*/
Public Function Delete ($key) {
if (Emptyempty ($key)) {
throw new Cacheexception ("Missing argument 1 for Cache_file::d elete ()");
}
$cacheFile = Self::_getcachefile ($key);
if ($cacheFile "target=" _blank ">! @unlink ($cacheFile)) {
throw new Cacheexception ("Cache file could not to be deleted");
}
return $this;
}
/**
* Whether the cache unit is locked
*
* @param string $key
* @return BOOL
*/
Public Function islocked ($key) {
$cacheFile = Self::_getcachefile ($key);
Clearstatcache ();
Return File_exists ($cacheFile. '. Lock ');
}
/**
* Lock
*
* @param string $key
* @return Cache_file
*/
Public function Lock ($key) {
$cacheFile = Self::_getcachefile ($key);
$cacheDir = DirName ($cacheFile);
if (!is_dir ($cacheDir)) {
if (mkdir ($cacheDir "target=" _blank ">! @mkdir ($cacheDir, 0755, True)) {
if (!is_dir ($cacheDir)) {
throw new Cacheexception ("Could not make cache directory");
}
}
}
To set the access and modification time of a cache lock file
@touch ($cacheFile. '. Lock ');
return $this;
}
/**
* Unlock
*
* @param string $key
* @return Cache_file
*/
Public function Unlock ($key) {
$cacheFile = Self::_getcachefile ($key);
@unlink ($cacheFile. '. Lock ');
return $this;
}
/**
* Set File cache directory
* @param string $dir
* @return Cache_file
*/
protected function _setcachedir ($dir) {
$this->_cachesdir = RTrim (str_replace (' \ \ ', '/', trim ($dir)), '/');
Clearstatcache ();
if (!is_dir ($this->_cachesdir)) {
mkdir ($this->_cachesdir, 0755, true);
}
//
return $this;
}
/**
* Empty All Caches
*
* @return Cache_file
*/
Public Function Clear () {
Traverse Directory Cleanup Cache
$cacheDir = $this->_cachesdir;
$d = Dir ($cacheDir);
while (false!== ($entry = $d->read ())) {
if ('. ' = = $entry [0]) {
Continue
}
$cacheEntry = $cacheDir. '/' . $entry;
if (Is_file ($cacheEntry)) {
@unlink ($cacheEntry);
} elseif (Is_dir ($cacheEntry)) {
Cache folder has level two
$d 2 = dir ($cacheEntry);
while (false!== ($entry = $d 2->read ())) {
if ('. ' = = $entry [0]) {
Continue
}
$cacheEntry. = '/'. $entry;
if (Is_file ($cacheEntry)) {
@unlink ($cacheEntry);
}
}
$d 2->close ();
}
}
$d->close ();
return $this;
}
}
/**
* Data structure of the cache unit
* Array (
* ' Time ' => (),//timestamp when Cache writes
* ' expire ' => $expire,//cache expiration Time
* ' Valid ' => true,//cache is valid
* ' Data ' => $value//Cached value
* );
*/
Final class Cache {
/**
* Cache Expiration Time Length (s)
*
* @var int
*/
Private $_expire = 3600;
/**
* Cache Processing Class
*
* @var Cache_abstract
*/
Private $_storage = null;
/**
* @return Cache
*/
static public Function Createcache ($cacheClass = ' cache_file ') {
return new self ($cacheClass);
}
Private function __construct ($cacheClass) {
$this->_storage = new $cacheClass ();
}
/**
* Set Cache
*
* @param string $key
* @param mixed $value
* @param int $expire
*/
Public function set ($key, $value, $expire = False) {
if (! $expire) {
$expire = $this->_expire;
}
$this->_storage->checklock ($key);
$data = Array (' Time ' => time (), ' expire ' => $expire, ' valid ' => true, ' data ' => $value);
$this->_storage->lock ($key);
try {
$this->_storage->store ($key, $data);
$this->_storage->unlock ($key);
catch (Cacheexception $e) {
$this->_storage->unlock ($key);
Throw $e;
}
}
/**
* Read Cache
*
* @param string $key
* @return Mixed
*/
Public function Get ($key) {
$data = $this->fetch ($key);
if ($data && $data [' valid '] &&! $data [' isexpired ']) {
return $data [' data '];
}
return false;
}
/**
* Read cache, including expired and invalid, get complete storage structure
*
* @param string $key
*/
Public function Fetch ($key) {
$this->_storage->checklock ($key);
$data = $this->_storage->fetch ($key);
if ($data) {
$data [' isexpired '] = (Time ()-$data [' time ']) > $data [' Expire ']? True:false;
return $data;
}
return false;
}
/**
* Delete Cache
*
* @param string $key
*/
Public Function Delete ($key) {
$this->_storage->checklock ($key)
->lock ($key)
->delete ($key)
->unlock ($key);
}
Public Function Clear () {
$this->_storage->clear ();
}
/**
* Set Cache to invalid
*
* @param string $key
*/
Public Function Setinvalidate ($key) {
$this->_storage->checklock ($key)
->lock ($key);
try {
$data = $this->_storage->fetch ($key);
if ($data) {
$data [' valid '] = false;
$this->_storage->store ($key, $data);
}
$this->_storage->unlock ($key);
catch (Cacheexception $e) {
$this->_storage->unlock ($key);
Throw $e;
}
}
/**
* Set cache expiration Time (s)
*
* @param int $expire
*/
Public Function Setexpire ($expire) {
$this->_expire = (int) $expire;
return $this;
}
}