PHP Cache Implementation code and detailed comments
Last Update:2018-04-04
Source: Internet
Author: User
PHP Cache Implementation implements apc and file caching, and inherits Cache_Abstract to call a third-party cache tool. Refer to the cache class and apc of shindig.
The code is as follows:
Class CacheException extends Exception {}
/**
* Cache abstract class
*/
Abstract class Cache_Abstract {
/**
* Read cache variables
*
* @ Param string $ key cache subscript
* @ Return mixed
*/
Abstract public function fetch ($ key );
/**
* Cache variables
*
* @ Param string $ key: cache variable subscript
* @ Param string $ value the cached variable value
* @ Return bool
*/
Abstract public function store ($ key, $ value );
/**
* Delete cache variables
*
* @ Param string $ key cache subscript
* @ Return Cache_Abstract
*/
Abstract public function delete ($ key );
/**
* Clear (delete) all caches
*
* @ Return Cache_Abstract
*/
Abstract public function clear ();
/**
* Lock cache variables
*
* @ Param string $ key cache subscript
* @ Return Cache_Abstract
*/
Abstract public function lock ($ key );
/**
* Unlock cache variables
*
* @ Param string $ key cache subscript
* @ Return Cache_Abstract
*/
Abstract public function unlock ($ key );
/**
* Whether the cache variable is locked
*
* @ Param string $ key cache subscript
* @ Return bool
*/
Abstract public function isLocked ($ key );
/**
* Make sure that the instance is not locked.
* You can perform a maximum of $ tries sleep waiting for unlocking. if the time-out period expires, the system skips and unlocks the tries.
*
* @ 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); // you can perform a maximum of ten sleep tasks and wait for unlocking. if the time-out period is exceeded and unlocked
$ This-> isLocked ($ key) & $ this-> unlock ($ key );
Return $ this;
}
}
/**
* APC extension cache implementation
*
*
* @ Category Mjie
* @ Package Cache
* @ Author streamline Meng Chun
* @ Copyright Copyright (c) 2008-
* @ License New BSD License
* @ Version $ Id: Cache/Apc. php version 2010-04-18 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 a 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 the cache unit
*
* @ Param string $ key
* @ Return Cache_Apc
*/
Public function lock ($ key ){
Apc_store ($ this-> _ storageKey ($ key). '. lock', '', 5 );
Return $ this;
}
/**
* Cache unit unlocking
*
* @ Param string $ key
* @ Return Cache_Apc
*/
Public function unlock ($ key ){
Apc_delete ($ this-> _ storageKey ($ key). '. lock ');
Return $ this;
}
/**
* Complete cache name
*
* @ Param string $ key
* @ Return string
*/
Private function _ storageKey ($ key ){
Return $ this-> _ prefix. '_'. $ key;
}
}
/**
* File cache implementation
*
*
* @ Category Mjie
* @ Package Cache
* @ Author streamline Meng Chun
* @ Copyright Copyright (c) 2008-
* @ License New BSD License
* @ Version $ Id: Cache/File. php version cmpan $
*/
Class Cache_File extends Cache_Abstract {
Protected $ _ cachesDir = 'cache ';
Public function _ construct (){
If (defined ('data _ dir ')){
$ This-> _ setCacheDir (DATA_DIR. '/cache ');
}
}
/**
* Getting 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, the cached file is in the PHP file format and" 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, the cached file is in the PHP file format and" Start"
*
* @ Param string $ key: cache variable subscript
* @ Param string $ value the cached variable value
* @ 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 ("cocould not make cache directory ");
}
}
Return @ file_put_contents ($ cacheFile ,' '. Serialize ($ value ));
}
/**
* Delete cache variables
*
* @ Param string $ key cache subscript
* @ Return Cache_File
*/
Public function delete ($ key ){
If (emptyempty ($ key )){
Throw new CacheException ("Missing argument 1 for Cache_File: delete ()");
}
$ CacheFile = self: _ getCacheFile ($ key );
If ($ cacheFile "target =" _ blank ">! @ Unlink ($ cacheFile )){
Throw new CacheException ("Cache file cocould not 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 ("cocould not make cache directory ");
}
}
}
// Set the access and modification time of the 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 the 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;
}
/**
* Clear all caches
*
* @ Return Cache_File
*/
Public function clear (){
// Clear the cache by traversing the Directory
$ 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 )){
// The cache folder has two levels
$ D2 = dir ($ cacheEntry );
While (false! ==( $ Entry = $ d2-> read ())){
If ('.' = $ entry [0]) {
Continue;
}
$ CacheEntry. = '/'. $ entry;
If (is_file ($ cacheEntry )){
@ Unlink ($ cacheEntry );
}
}
$ D2-> close ();
}
}
$ D-> close ();
Return $ this;
}
}
/**
* Data structure of the cache unit
* Array (
* 'Time' => time (), // The timestamp when the cache is written.
* 'Expire '=> $ expire, // cache expiration time
* 'Valid' => true, // whether the cache is valid
* 'Data' => $ value // cached value
*);
*/
Final class Cache {
/**
* Cache Expiration Time (s)
*
* @ Var int
*/
Private $ _ expire = 3600;
/**
* Cache processing
*
* @ 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, to obtain the 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 the 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;
}
}