一个PHP页面缓存类 修改后可作Emlog缓存插件
最近,细细看了许多关于缓存的文章,有程序级的、非程序级的、内存缓存、文件缓存等等,感觉获益良多,于是为巩固知识,强化记忆,自己也多动动手去写写关于缓存面的程序。 这是自己写的一个PHP文件缓存类,此类仅是对整页页面缓存,原理是对php响应http请求后编译生成的html代码,全部以文件形式存在服务器上,在缓存有效期内,直接读取访问缓存,缓存失效时,那么就像平时访问php一样查询数据库获取数据,同时此类为页面产生缓存文件,以便下次访问,减少对数据等查询损耗。 当然,这个类只不过是入门级的写法,简单实现,此为在整页缓存,类似于生成HTML成静态,只是此类可缓存一段时间并自动重新生成。还有许多CMS等系统常用到文件缓存,例如把数据库的表存到文件,又或者把部分数据存到文件中,有以php文件形式、有以序列化后存储的形式,原理都差不多,需求不同罢了,都可以实现相同的缓存效果。 文件缓存只是其中一种,还有其实缓存方式,例如php缓冲器:eaccelerator, apc, phpa,xcache等,基于反向代理的Web缓存:Nginx,SQUID,mod_proxy,常见的内存缓存如Memcached等。 代码: Copy to Clipboard <?php class fancyCache { private static $_instance = NULL; protected $_options =array(); /** * 初始化构造函数 * $cacheDir : 缓存文件目录 * $expire : 缓存文件有效期,单位为秒 * $file_ext : 缓存文件后缀 */ public static function init($cacheDir='./cache',$expire=1800,$file_ext='.htm') { $instance = self::getInstance(); //判断缓存目录是否有效 if($instance->isValidCacheDir($cacheDir)) { $instance->_options['cache_dir']=rtrim($cacheDir,'/') . '/'; $instance->_options['expire']=$expire; $instance->_options['file_ext']=$file_ext; $instance->_options['cache_file_url']=$instance->getCacheFileUrl(); if($_SERVER['REQUEST_METHOD']=='GET') { //缓存未过期则读取缓存文件 if($instance->isExpired()) { $instance->readCache(); exit; } else { //自动缓存 ob_start(array($instance,"autoCache")); } } else { //不是GET请求则删除缓存 if(file_exists($instance->_options['cache_file_url']))unlink($instance->_options['cache_file_url']); } } } /** * 获取当前对象 */ public static function getInstance() { if(self::$_instance==NULL) { self::$_instance=new self(); } return self::$_instance; } /** * 读取缓存 */ protected function readCache() { $instance =self::getInstance(); $fp =fopen($instance->_options['cache_file_url'],'rb'); fpassthru($fp); fclose($fp); } /** * 自动写入缓存 */ public function autoCache($contents) { $instance = self::getInstance(); if($fp=fopen($instance->_options['cache_file_url'],'wb')) { if (flock($fp,LOCK_EX)) { ftruncate($fp,0); fwrite($fp,$contents); fclose($fp); chmod($instance->_options['cache_file_url'],0777); } } self::DelOldCache(); return $contents; } /** * 删除所有过期缓存 */ protected function DelOldCache() { $instance = self::getInstance(); chdir($instance->_options['cache_dir']); foreach (glob("*/*".$instance->_options['file_ext']) as $file) { if(time()-filemtime($file)>$instance->_options['expire'])unlink($file); } } /** * 验证缓存是否有效 * return true 已过期 */ protected function isExpired() { $instance = self::getInstance(); if(!file_exists($instance->_options['cache_file_url']))return false; if(time()-filemtime($instance->_options['cache_file_url'])>$instance->_options['expire'])return false; return true; } /** * 验证缓存目录是否存在,不存在则创建 * return true 存在或创建成功 */ protected function isValidCacheDir($cacheDir) { $instance = self::getInstance(); $cacheDir=rtrim($cacheDir,'/') . '/'; if(!file_exists($cacheDir)){ try { mkdir($cacheDir,0777); chmod($cacheDir,0777); } catch(Exception $e) { echo 'Failed to create cache dir!'; return false; } } //创建缓存文件子目录 $cacheFileDir=$cacheDir.substr(md5($instance->getPageUrl()),1); if(!file_exists($cacheFileDir)) { try { mkdir($cacheFileDir,0777); chmod($cacheFileDir,0777); } catch(Exception $e) { echo 'Failed to create cache dir!'; return false; } } return true; } /** * 取得缓存文件路径 */ protected function getCacheFileUrl() { $instance =self::getInstance(); $pageUrl =md5($instance->getPageUrl()); return $instance->_options['cache_dir'].substr($pageUrl,1).'/'.$pageUrl.$instance->_options['file_ext']; } /** * 取得当前访问页面完整url */ protected function getPageUrl() { $url = ''; if (isset($_SERVER['REQUEST_URI'])) { $url = $_SERVER['REQUEST_URI']; } else { $url = $_SERVER['PHP_SELF']; $url .= empty($_SERVER['QUERY_STRING'])?'':'?'.$_SERVER['QUERY_STRING']; } return $url; } } ?> 本博使用Emlog程序,所以本人对类稍做了修改以作Emlog缓存插 1、在类中加上(注释不能删) Copy to Clipboard /* Plugin Name: fancyCache-页面缓存 Version: beta 1.0 Plugin URL: http://meego123.net/ Description: 使用fancyCache可用页面自动缓存 Author: Jamin Author Email: wenjingmin@gmail.com Author URL: http://meego123.net/ */ !defined('EMLOG_ROOT') && exit('access deined!'); addAction('index_header',fancyCache::init(EMLOG_ROOT."/content/fancyCache",60*60*24)); 2、文件名存为fancycache.php,并建立同名文件夹,将fancycache.php放到fancycache文件夹中,并一同放到Emlog插件目录/content/plugins下 3、到Emlog后台“功能扩展” -- ”插件“,开启插件即可 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |