最近,細細看了許多關於緩存的文章,有程序級的、非程序級的、內存緩存、文件緩存等等,感覺獲益良多,於是為鞏固知識,強化記憶,自己也多動動手去寫寫關於緩存面的程序。
這是自己寫的一個PHP文件緩存類,此類僅是對整頁頁面緩存,原理是對php響應http請求後編譯生成的html代碼,全部以文件形式存在服務器上,在緩存有效期內,直接讀取訪問緩存,緩存失效時,那麼就像平時訪問php一樣查詢數據庫獲取數據,同時此類為頁面產生緩存文件,以便下次訪問,減少對數據等查詢損耗。
當然,這個類只不過是入門級的寫法,簡單實現,此為在整頁緩存,類似於生成HTML成靜態,只是此類可緩存一段時間並自動重新生成。還有許多CMS等系統常用到文件緩存,例如把數據庫的表存到文件,又或者把部分數據存到文件中,有以php文件形式、有以序列化後存儲的形式,原理都差不多,需求不同罷了,都可以實現相同的緩存效果。
文件緩存只是其中一種,還有其實緩存方式,例如php緩沖器:eaccelerator, apc, phpa,xcache等,基於反向代理的Web緩存:Nginx,SQUID,mod_proxy,常見的內存緩存如Memcached等。
代碼:
Copy to Clipboard引用的內容:[www.bkjia.com]
<?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()),0,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,0,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引用的內容:[www.bkjia.com]
/*
Plugin Name: fancyCache-頁面緩存
Version: beta 1.0
Plugin URL: http://meego123.net/
Description: 使用fancyCache可用頁面自動緩存
Author: Jamin
Author Email:
[email protected] 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後台“功能擴展” -- ”插件“,開啟插件即可
本文來源:http://meego123.net/?post=127