一個簡單的PHP緩存思路的實現

PHP生成靜態頁面的緩存方式
服務器君一共花費了168.813 ms進行了5次數據庫查詢,努力地為您提供了這個頁面。
試試閱讀模式?希望聽取您的建議

一般來說,緩存的目的是把數據放在一個地方讓訪問的更快點,毫無疑問,內存是最快的,但是,幾百M的數據能往內存放么?這不現實,當然,有的時候臨時放如服務器緩存,如ob_start()這個緩存頁面開啟的話在發送文件頭之前頁面內容都被緩存在內存中,知道等頁面輸出自動清楚或者等待 ob_get_contents的返回,或者被ob_end_clean顯示的清除,這在靜態頁面的生成中能很好的利用,在模板中能得到很好的體現,我的這篇文章深入的討論了:談PHP生成靜態頁面,這是一種方式,但這是臨時性的,不是解決我們問題的好方法。

另外,在asp中有一對象application,可以保存公用的參數,這也算點緩存,但在php,我至今沒看到開發者產出這種對象,的確,沒必要。asp。net的頁面緩存技術就用的是viewstate,而cache就是文件關聯,(不一定準確),文件被修改,更新緩存,文件沒被修改而且不超時,就讀取緩存,返回結果,就是這個思路,看看這個源碼:

class cache { 
/* 
Class Name: cache 
Description: control to cache data,$cache_out_time is a array to save cache date time out. 
*/ 
private $cache_dir; 
private $expireTime=180;//緩存的時間是 60 秒 
function __construct($cache_dirname)
{ 
	if([email protected]_dir($cache_dirname))
	{ 
		if([email protected]($cache_dirname,0777))
		{ 
			$this->warn('緩存文件不存在而且不能創建,需要手動創建.'); 
			return false; 
		} 
	} 
	$this->cache_dir = $cache_dirname; 
}
function __destruct()
{ 
	echo 'Cache class bye.'; 
} 
function get_url() 
{ 
	if (!isset($_SERVER['REQUEST_URI'])) 
	{ 
		$url = $_SERVER['REQUEST_URI']; 
	}
	else
	{ 
		$url = $_SERVER['SCRIPT_NAME']; 
		$url .= (!empty($_SERVER['QUERY_STRING'])) ? '?' . $_SERVER['QUERY_STRING'] : ''; 
	} 
	return $url; 
} 
function warn($errorstring)
{ 
	echo "發生錯誤:
	".$errorstring."
	"; 
} 
function cache_page($pageurl,$pagedata)
{ 
	if(!$fso=fopen($pageurl,'w'))
	{ 
		$this->warns('無法打開緩存文件.');//trigger_error 
		return false; 
	} 
	
	if(!flock($fso,LOCK_EX))
	{
		//LOCK_NB,排它型鎖定 
		$this->warns('無法鎖定緩存文件.');
		//trigger_error 
		return false; 
	} 
	
	if(!fwrite($fso,$pagedata))
	{
		//寫入字節流,serialize寫入其他格式 
		$this->warns('無法寫入緩存文件.');
		//trigger_error 
		return false; 
	} 
	flock($fso,LOCK_UN);//釋放鎖定 
	fclose($fso); 
	return true; 
} 
function display_cache($cacheFile)
{ 
	if(!file_exists($cacheFile))
	{ 
		$this->warn('無法讀取緩存文件.');//trigger_error 
		return false; 
	} 
	echo '讀取緩存文件:'.$cacheFile; 
	//return unserialize(file_get_contents($cacheFile)); 
	$fso = fopen($cacheFile, 'r'); 
	$data = fread($fso, filesize($cacheFile)); 
	fclose($fso); 
	return $data; 
} 
function readData($cacheFile='default_cache.txt')
{ 
	$cacheFile = $this->cache_dir."/".$cacheFile; 
	if(file_exists($cacheFile)&&filemtime($cacheFile)>(time()-$this->expireTime))
	{ 
		$data=$this->display_cache($cacheFile); 
	}
	else
	{ 
		$data="from here wo can get it from mysql database,update time is ".date('l dS of F Y h:i:s A').",過期時間是:".date('l dS of F Y h:i:s A',time()+$this->expireTime)."----------"; 
		$this->cache_page($cacheFile,$data); 
	} 
	return $data; 
} 
} 
?> 

這個緩存類有2個屬性:

private $cache_dir; 
private $expireTime=180; 

$cache_dir是緩存文件所放的相對網站目錄的父目錄, $expireTime(注釋一)是我們緩存的數據過期的時間,主要是這個思路: 當數據或者文件被加載的時候,先判斷緩存文件存在不,返回false ,文件最后修改時間和緩存的時間和比當前時間大不,大的話說明緩存還沒到期,小的話返回false,當返回false的時候,讀取原始數據,寫入緩存文件中,返回數據。

接著看程序:

function __construct($cache_dirname)
{ 
	if([email protected]_dir($cache_dirname))
	{ 
		if([email protected]($cache_dirname,0777))
		{ 
			$this->warn('緩存文件不存在而且不能創建,需要手動創建.'); 
			return false; 
		} 
	} 
	$this->cache_dir = $cache_dirname; 
} 

當類第一次被實例的時候構造默認函數帶參數緩存文件名稱,如文件不存在,創建一個有編輯權限的文件夾,創建失敗的時候拋出異常。然后把cache類的 $cache_dir屬性設置為這個文件夾名稱,我們的所有緩存文件都是在這個文件夾下面的。

function __destruct(){ 
	echo 'Cache class bye.'; 
} 

這是class類的析構函數,為了演示,我們輸出一個字符串表示我們釋放cache類資源成功。

function warn($errorstring){ 
	echo "發生錯誤:
	".$errorstring."
	"; 
} 

這個方法輸出錯誤信息。

function get_url() 
{ 
	if (!isset($_SERVER['REQUEST_URI'])) 
	{ 
		$url = $_SERVER['REQUEST_URI']; 
	}
	else
	{ 
		$url = $_SERVER['SCRIPT_NAME']; 
		$url .= (!empty($_SERVER['QUERY_STRING'])) ? '?' . $_SERVER['QUERY_STRING'] : ''; 
	} 
	return $url; 
} 

這個方法返回當前url的信息,這是我看國外很多人的cms系統這樣做,主要是緩存x。php?page=1,x。php?page=2,等這種文件的,這里列出是為了擴展的這個cache類功能的。

function cache_page($pageurl,$pagedata)
{ 
	if(!$fso=fopen($pageurl,'w'))
	{ 
		$this->warns('無法打開緩存文件.');//trigger_error 
		return false; 
	} 
	if(!flock($fso,LOCK_EX))
	{
		//LOCK_NB,排它型鎖定 
		$this->warns('無法鎖定緩存文件.');//trigger_error 
		return false; 
	} 
	if(!fwrite($fso,$pagedata))
	{
		//寫入字節流,serialize寫入其他格式 
		$this->warns('無法寫入緩存文件.');//trigger_error 
		return false; 
	} 
	flock($fso,LOCK_UN);//釋放鎖定 
	fclose($fso); 
	return true; 
} 

cache_page方法分別傳入的是緩存的文件名稱和數據,這是把數據寫到文件里的方法,先用fopen打開文件,然后調用句柄鎖定這個文件,然后用fwrite寫入文件,最后釋放這個句柄,任何一步發生錯誤將拋出錯誤。 您可能看到這個注釋:

寫入字節流,serialize寫入其他格式,順便一提的是如果我們要把一個數組,(可以從MySQL數據庫里面select查詢除了的結果)用serialize函數寫入,用unserialize讀取到原來的類型。

function display_cache($cacheFile)
{ 
	if(!file_exists($cacheFile))
	{ 
		$this->warn('無法讀取緩存文件.');//trigger_error 
		return false; 
	} 
	echo '讀取緩存文件:'.$cacheFile; 
	//return unserialize(file_get_contents($cacheFile)); 
	$fso = fopen($cacheFile, 'r'); 
	$data = fread($fso, filesize($cacheFile)); 
	fclose($fso); 
	return $data; 
} 

這是由文件名稱讀取緩存的方法,直接打開文件,讀取全部,如果文件不存在的或者無法讀取的話返回false,當然,你感到不人性的話,可以重新生成緩存。

function readData($cacheFile='default_cache.txt')
{ 
	$cacheFile = $this->cache_dir."/".$cacheFile; 
	if(file_exists($cacheFile)&&filemtime($cacheFile)>(time()-$this->expireTime))
	{ 
		$data=$this->display_cache($cacheFile); 
	}
	else
	{ 
		$data="from here wo can get it from mysql database,update time is ".date('l dS of F Y h:i:s A').",過期時間是:".date('l dS of F Y h:i:s A',time()+$this->expireTime)."----------"; 
	$this->cache_page($cacheFile,$data); 
	} 
	return $data; 
} 

這個函數是我們調用的方法,可以寫成接口的方法,由傳入參數判斷文件存在不,文件最后修改時間+expireTime的時間是不是過了當前時間 (大于的話說明沒有過期),如果文件不存在或者已經過期,重新加載原始數據,這里,為了簡單期間,我們是直接源是字符串,您可以把cache類繼承某類, 取到數據庫的數據。

注釋一:這個緩存的時間您可以自己調,可以根據時間情況讀取數組,xml,緩存等,請按照您的方便,值得一提的是緩存的時間(也就是緩存的key)也用緩存控制,。這在cms系統中被廣泛使用,他們把要更新的key放在緩存中,非常容易控制全戰。

注釋二:php5開始支持類繼承,這是讓人興奮的,把網站全局休息寫在一個配置的類里面,再寫與數據層交互的類(如與MySQL交互的類),我們的這個cache類繼承數據交互的類,可以非常容易的讀取數據庫,這是外話,此處不再展開,有時間和大家詳談。

特別說明,這個類文件針對的php5以上版本,其他版本的請不要使用類。

本文地址:http://www.824886.live/librarys/veda/detail/1221,歡迎訪問原出處。

不打個分嗎?

轉載隨意,但請帶上本文地址:

http://www.824886.live/librarys/veda/detail/1221

如果你認為這篇文章值得更多人閱讀,歡迎使用下面的分享功能。
小提示:您可以按快捷鍵 Ctrl + D,或點此 加入收藏。

大家都在看

閱讀一百本計算機著作吧,少年

很多人覺得自己技術進步很慢,學習效率低,我覺得一個重要原因是看的書少了。多少是多呢?起碼得看3、4、5、6米吧。給個具體的數量,那就100本書吧。很多人知識結構不好而且不系統,因為在特定領域有一個足夠量的知識量+足夠良好的知識結構,系統化以后就足以應對大量未曾遇到過的問題。

奉勸自學者:構建特定領域的知識結構體系的路徑中再也沒有比學習該專業的專業課程更好的了。如果我的知識結構體系足以囊括面試官的大部分甚至吞并他的知識結構體系的話,讀到他言語中的一個詞我們就已經知道他要表達什么,我們可以讓他坐“上位”畢竟他是面試官,但是在知識結構體系以及心理上我們就居高臨下。

所以,閱讀一百本計算機著作吧,少年!

《重構:改善既有代碼的設計》 福勒(Martin Fowler) (作者), 熊節 (譯者)

《重構:改善既有代碼的設計》清晰地揭示了重構的過程,解釋了重構的原理和最佳實踐方式,并給出了何時以及何地應該開始挖掘代碼以求改善。書中給出了70多個可行的重構,每個重構都介紹了一種經過驗證的代碼變換手法的動機和技術?!吨貥?改善既有代碼的設計》提出的重構準則將幫助你一次一小步地修改你的代碼,從而減少了開發過程中的風險。

更多計算機寶庫...

云南快乐十分走势一定牛 网盛棋牌app下载 江西多乐彩任三技巧 管家婆三肖必中一肖 广西11选五走势图一定牛 广西棋牌北海十三张 模拟股票软件手机版 欢乐广东麻将推倒胡 炒股杠杆哪个平台好 豪利棋牌天天送6金币 今日股市行情最新消