zl程序教程

您现在的位置是:首页 >  后端

当前栏目

PHP缓存实现代码及详细注释

PHP缓存代码 实现 详细 注释
2023-06-13 09:14:18 时间
复制代码代码如下:

classCacheExceptionextendsException{}
/**
*缓存抽象类
*/
abstractclassCache_Abstract{
/**
*读缓存变量
*
*@paramstring$key缓存下标
*@returnmixed
*/
abstractpublicfunctionfetch($key);

/**
*缓存变量
*
*@paramstring$key缓存变量下标
*@paramstring$value缓存变量的值
*@returnbool
*/
abstractpublicfunctionstore($key,$value);

/**
*删除缓存变量
*
*@paramstring$key缓存下标
*@returnCache_Abstract
*/
abstractpublicfunctiondelete($key);

/**
*清(删)除所有缓存
*
*@returnCache_Abstract
*/
abstractpublicfunctionclear();

/**
*锁定缓存变量
*
*@paramstring$key缓存下标
*@returnCache_Abstract
*/
abstractpublicfunctionlock($key);
/**
*缓存变量解锁
*
*@paramstring$key缓存下标
*@returnCache_Abstract
*/
abstractpublicfunctionunlock($key);
/**
*取得缓存变量是否被锁定
*
*@paramstring$key缓存下标
*@returnbool
*/
abstractpublicfunctionisLocked($key);
/**
*确保不是锁定状态
*最多做$tries次睡眠等待解锁,超时则跳过并解锁
*
*@paramstring$key缓存下标
*/
publicfunctioncheckLock($key){
if(!$this->isLocked($key)){
return$this;
}

$tries=10;
$count=0;
do{
usleep(200);
$count++;
}while($count<=$tries&&$this->isLocked($key));//最多做十次睡眠等待解锁,超时则跳过并解锁
$this->isLocked($key)&&$this->unlock($key);

return$this;
}
}

/**
*APC扩展缓存实现
*
*
*@categoryMjie
*@packageCache
*@author流水孟春
*@copyrightCopyright(c)2008-<cmpan(at)qq.com>
*@licenseNewBSDLicense
*@version$Id:Cache/Apc.php版本号2010-04-1823:02cmpan$
*/
classCache_ApcextendsCache_Abstract{

protected$_prefix="cache.mjie.net";

publicfunction__construct(){
if(!function_exists("apc_cache_info")){
thrownewCacheException("apcextensiondidn\"tinstalled");
}
}

/**
*保存缓存变量
*
*@paramstring$key
*@parammixed$value
*@returnbool
*/
publicfunctionstore($key,$value){
returnapc_store($this->_storageKey($key),$value);
}

/**
*读取缓存
*
*@paramstring$key
*@returnmixed
*/
publicfunctionfetch($key){
returnapc_fetch($this->_storageKey($key));
}

/**
*清除缓存
*
*@returnCache_Apc
*/
publicfunctionclear(){
apc_clear_cache();
return$this;
}

/**
*删除缓存单元
*
*@returnCache_Apc
*/
publicfunctiondelete($key){
apc_delete($this->_storageKey($key));
return$this;
}

/**
*缓存单元是否被锁定
*
*@paramstring$key
*@returnbool
*/
publicfunctionisLocked($key){
if((apc_fetch($this->_storageKey($key).".lock"))===false){
returnfalse;
}

returntrue;
}

/**
*锁定缓存单元
*
*@paramstring$key
*@returnCache_Apc
*/
publicfunctionlock($key){
apc_store($this->_storageKey($key).".lock","",5);
return$this;
}

/**
*缓存单元解锁
*
*@paramstring$key
*@returnCache_Apc
*/
publicfunctionunlock($key){
apc_delete($this->_storageKey($key).".lock");
return$this;
}

/**
*完整缓存名
*
*@paramstring$key
*@returnstring
*/
privatefunction_storageKey($key){
return$this->_prefix."_".$key;
}
}
/**
*文件缓存实现
*
*
*@categoryMjie
*@packageCache
*@author流水孟春
*@copyrightCopyright(c)2008-<cmpan(at)qq.com>
*@licenseNewBSDLicense
*@version$Id:Cache/File.php版本号2010-04-1816:46cmpan$
*/
classCache_FileextendsCache_Abstract{

protected$_cachesDir="cache";

publicfunction__construct(){
if(defined("DATA_DIR")){
$this->_setCacheDir(DATA_DIR."/cache");
}
}

/**
*获取缓存文件
*
*@paramstring$key
*@returnstring
*/
protectedfunction_getCacheFile($key){
return$this->_cachesDir."/".substr($key,0,2)."/".$key.".php";
}
/**
*读取缓存变量
*为防止信息泄露,缓存文件格式为php文件,并以"<?phpexit;?>"开头
*
*@paramstring$key缓存下标
*@returnmixed
*/
publicfunctionfetch($key){
$cacheFile=self::_getCacheFile($key);
if(file_exists($cacheFile)&&is_readable($cacheFile)){
returnunserialize(@file_get_contents($cacheFile,false,NULL,13));
}
returnfalse;
}
/**
*缓存变量
*为防止信息泄露,缓存文件格式为php文件,并以"<?phpexit;?>"开头
*
*@paramstring$key缓存变量下标
*@paramstring$value缓存变量的值
*@returnbool
*/
publicfunctionstore($key,$value){
$cacheFile=self::_getCacheFile($key);
$cacheDir=dirname($cacheFile);
if(!is_dir($cacheDir)){
if(mkdir($cacheDir"target="_blank">!@mkdir($cacheDir,0755,true)){
thrownewCacheException("Couldnotmakecachedirectory");
}
}
return@file_put_contents($cacheFile,"<?phpexit;?>".serialize($value));
}
/**
*删除缓存变量
*
*@paramstring$key缓存下标
*@returnCache_File
*/
publicfunctiondelete($key){
if(emptyempty($key)){
thrownewCacheException("Missingargument1forCache_File::delete()");
}

$cacheFile=self::_getCacheFile($key);
if($cacheFile"target="_blank">!@unlink($cacheFile)){
thrownewCacheException("Cachefilecouldnotbedeleted");
}
return$this;
}
/**
*缓存单元是否已经锁定
*
*@paramstring$key
*@returnbool
*/
publicfunctionisLocked($key){
$cacheFile=self::_getCacheFile($key);
clearstatcache();
returnfile_exists($cacheFile.".lock");
}
/**
*锁定
*
*@paramstring$key
*@returnCache_File
*/
publicfunctionlock($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)){
thrownewCacheException("Couldnotmakecachedirectory");
}
}
}
//设定缓存锁文件的访问和修改时间
@touch($cacheFile.".lock");
return$this;
}

/**
*解锁
*
*@paramstring$key
*@returnCache_File
*/
publicfunctionunlock($key){
$cacheFile=self::_getCacheFile($key);
@unlink($cacheFile.".lock");
return$this;
}
/**
*设置文件缓存目录
*@paramstring$dir
*@returnCache_File
*/
protectedfunction_setCacheDir($dir){
$this->_cachesDir=rtrim(str_replace("\\","/",trim($dir)),"/");
clearstatcache();
if(!is_dir($this->_cachesDir)){
mkdir($this->_cachesDir,0755,true);
}
//
return$this;
}

/**
*清空所有缓存
*
*@returnCache_File
*/
publicfunctionclear(){
//遍历目录清除缓存
$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)){
//缓存文件夹有两级
$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;
}
}
/**
*缓存单元的数据结构
*array(
*"time"=>time(),//缓存写入时的时间戳
*"expire"=>$expire,//缓存过期时间
*"valid"=>true,//缓存是否有效
*"data"=>$value//缓存的值
*);
*/
finalclassCache{
/**
*缓存过期时间长度(s)
*
*@varint
*/
private$_expire=3600;
/**
*缓存处理类
*
*@varCache_Abstract
*/
private$_storage=null;
/**
*@returnCache
*/
staticpublicfunctioncreateCache($cacheClass="Cache_File"){
returnnewself($cacheClass);
}
privatefunction__construct($cacheClass){
$this->_storage=new$cacheClass();
}
/**
*设置缓存
*
*@paramstring$key
*@parammixed$value
*@paramint$expire
*/
publicfunctionset($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;
}
}
/**
*读取缓存
*
*@paramstring$key
*@returnmixed
*/
publicfunctionget($key){
$data=$this->fetch($key);
if($data&&$data["valid"]&&!$data["isExpired"]){
return$data["data"];
}

returnfalse;
}
/**
*读缓存,包括过期的和无效的,取得完整的存贮结构
*
*@paramstring$key
*/
publicfunctionfetch($key){
$this->_storage->checkLock($key);
$data=$this->_storage->fetch($key);
if($data){
$data["isExpired"]=(time()-$data["time"])>$data["expire"]?true:false;
return$data;
}

returnfalse;
}
/**
*删除缓存
*
*@paramstring$key
*/
publicfunctiondelete($key){
$this->_storage->checkLock($key)
->lock($key)
->delete($key)
->unlock($key);
}

publicfunctionclear(){
$this->_storage->clear();
}
/**
*把缓存设为无效
*
*@paramstring$key
*/
publicfunctionsetInvalidate($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;
}
}

/**
*设置缓存过期时间(s)
*
*@paramint$expire
*/
publicfunctionsetExpire($expire){
$this->_expire=(int)$expire;
return$this;
}
}