詳解php緩存技術(shù)_第1頁
詳解php緩存技術(shù)_第2頁
詳解php緩存技術(shù)_第3頁
詳解php緩存技術(shù)_第4頁
詳解php緩存技術(shù)_第5頁
已閱讀5頁,還剩2頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

詳解php緩存技術(shù)先簡(jiǎn)單的說一下:PHP緩存技術(shù)WEB程序獲取信息的方式主要是查詢數(shù)據(jù)庫,當(dāng)數(shù)據(jù)庫不是很大的情況下不會(huì)有太大的問題.然而,隨著網(wǎng)站的發(fā)展,數(shù)據(jù)庫呈幾何級(jí)數(shù)的方式增長的時(shí)候,就會(huì)出現(xiàn)瓶頸.于是PHP緩存技術(shù)誕生了.PHP緩存技術(shù)工作時(shí),當(dāng)程序查詢數(shù)據(jù)的時(shí)候,會(huì)把相應(yīng)的結(jié)果序列化后保存到文件中,以后同樣的查詢語句就可以不用直接查詢數(shù)據(jù)庫,而是從緩存文件中獲得。這一改進(jìn)使得程序運(yùn)行速度得以太幅度提升.目前應(yīng)用PHP緩存技術(shù)比較流行的方法主要是Adodb+Smarty這樣的黃金搭檔.PHP緩存技術(shù)工作原理:首先看看adodb提供的數(shù)據(jù)緩存功能:1<?php2include('adodb.inc.php');#loadcodecommontoADOdb3$ADODB_CACHE_DIR='/usr/ADODB_cache';4$conn=&ADONewConnection('mysql');#createaconnection5$conn->PConnect('','userid',”,'agora');#connecttoMySQL,agoradb6$sql='selectCustomerName,CustomerIDfromcustomers';7$rs=$conn->CacheExecute(15,$sql);8?>如上,每次查詢數(shù)據(jù)的時(shí)候,會(huì)把相應(yīng)的結(jié)果序列化后保存到文件中,以后同樣的查詢語句就可以不用直接查詢數(shù)據(jù)庫,而是從緩存文件中獲得。再來看看Smarty提供的頁面緩存功能:1<?php2require('Smarty.class.php');3$smarty=newSmarty;4$smarty->caching=true;5if(!$smarty->is_cached('index.tpl')){//Nocacheavailable,dovariableassignmentshere.$contents=get_database_contents();$smarty->assign($contents);9}10$smarty->display('index.tpl');11?>12如上,每次訪問頁面的時(shí)候,都會(huì)先檢測(cè)相應(yīng)的緩存是否存在,如果不存在,就連接數(shù)據(jù)庫,得到數(shù)據(jù),完成模板變量的賦值,顯示頁面,同時(shí)生成緩存文件,這樣下次訪問的時(shí)候緩存文件就發(fā)揮作用了,而不會(huì)再執(zhí)行if塊的數(shù)據(jù)查詢語句了。當(dāng)然,在實(shí)際使用中會(huì)有很多東西要考慮,比如,有效期的設(shè)置,緩存組的設(shè)置等等,具體可以查看Smarty手冊(cè)中有關(guān)緩存(caching)的相關(guān)章節(jié)。以上兩個(gè)PHP流行組件緩存方式的側(cè)重點(diǎn)是不同的,對(duì)于Adodb的緩存而言,它緩存的是數(shù)據(jù),對(duì)于Smarty的緩存而言,它緩存的是頁面。其他提供緩存功

能的組件還有很多(如:PEAR::Cache_Lite等等),實(shí)際編程中使用哪個(gè)方案要具體情況具體分析,也可能會(huì)綜合使用。使用這些組件內(nèi)置的緩存方案有一個(gè)很明顯的好處是它們的實(shí)現(xiàn)對(duì)客戶端而言都很透明。只要進(jìn)行必要的設(shè)置(如:緩存時(shí)間,緩存目錄等等)就可以了,而不用過多考慮實(shí)現(xiàn)緩存的細(xì)節(jié)問題,系統(tǒng)會(huì)根據(jù)設(shè)置自動(dòng)管理緩存。但是其缺點(diǎn)也同樣明顯,因?yàn)槊看握?qǐng)求仍然要用PHP解析一遍,效率和純靜態(tài)相比還是大打折扣,在大的PV面前還是不能滿足要求,在這種情況下,僅僅做動(dòng)態(tài)緩存就不夠了,必須實(shí)現(xiàn)靜態(tài)緩存。PHP,一門最近幾年興起的web設(shè)計(jì)腳本語言,由于它的強(qiáng)大和可伸縮性,近幾年來得到長足的發(fā)展,php相比傳統(tǒng)的asp網(wǎng)站,在速度上有絕對(duì)的優(yōu)勢(shì),想mssql轉(zhuǎn)6萬條數(shù)據(jù)php如需要40秒,asp不下2分鐘.但是,由于網(wǎng)站的數(shù)據(jù)越來越多,我們渴求能更快速的調(diào)用數(shù)據(jù),不必要每次都從數(shù)據(jù)庫掉,我們可以從其他的地方,比方一個(gè)文件,或者某個(gè)內(nèi)存地址,這就是php的緩存技術(shù),也就是Cache技術(shù)詳細(xì)的說一下:一、緩存技術(shù):有些信息比方經(jīng)常不變的,但是還是能變的信息放在緩存中以加快顯示速度,這是很有價(jià)值的,所謂的緩存,通俗的理解就是一些保存在服務(wù)器端的共用信息.它是于服務(wù)器同生死的,我們?cè)诒4婢彺娴臅r(shí)候可以指定下次更新的時(shí)間的判斷,比方要在5分鐘更新一次,可以記錄上次更新的時(shí)間,和當(dāng)前時(shí)間比較,如果大于5分鐘,讀取數(shù)據(jù)庫,更新?lián)Q成,否則直接讀取緩存數(shù)據(jù),當(dāng)然,緩存需要客戶端用戶激活的,只需一次.ob_start()函數(shù):打開輸出緩沖區(qū).函數(shù)格式voidob_start(void)說明:當(dāng)緩沖區(qū)激活時(shí),所有來自PHP程序的非文件頭信息均不會(huì)發(fā)送,而是保存在內(nèi)部緩沖區(qū)。為了輸出緩沖區(qū)的內(nèi)容,可以使用ob_end_flush()或flush()輸出緩沖區(qū)的內(nèi)容。Flush:刷新緩沖區(qū)的內(nèi)容,輸出。函數(shù)格式:flush()說明:這個(gè)函數(shù)經(jīng)常使用,效率很高。ob_get_contents:返回內(nèi)部緩沖區(qū)的內(nèi)容。函數(shù)格式:stringob_get_contents(void)說明:這個(gè)函數(shù)會(huì)返回當(dāng)前緩沖區(qū)中的內(nèi)容,如果輸出緩沖區(qū)沒有激活,則返回FALSE.ob_get_length:返回內(nèi)部緩沖區(qū)的長度。函數(shù)格式:intob_get_length(void)說明:這個(gè)函數(shù)會(huì)返回當(dāng)前緩沖區(qū)中的長度;和ob_get_contents一樣,如果輸出緩沖區(qū)沒有激活,則返回FALSE.ob_end_clean:刪除內(nèi)部緩沖區(qū)的內(nèi)容,并且關(guān)閉內(nèi)部緩沖區(qū)函數(shù)格式:voidob_end_clean(void)說明:這個(gè)函數(shù)不會(huì)輸出內(nèi)部緩沖區(qū)的內(nèi)容而是把它刪除ob_end_flush:發(fā)送內(nèi)部緩沖區(qū)的內(nèi)容到瀏覽器,并且關(guān)閉輸出緩沖區(qū)函數(shù)格式:voidob_end_flush(void)說明:這個(gè)函數(shù)發(fā)送輸出緩沖區(qū)的內(nèi)容(如果有的話)ob_implicit_flush:打開或關(guān)閉絕對(duì)刷新函數(shù)格式:voidob_implicit_flush([intflag])說明:默認(rèn)為關(guān)閉緩沖區(qū),打開絕對(duì)輸出后,每個(gè)腳本輸出都直接發(fā)送到瀏覽器,不再需要調(diào)用flush()二、文件寫入:intfwrite(resourcehandle,stringstring[,intlength])fwrite()把string的內(nèi)容寫入文件指針handle處。如果指定了length,當(dāng)寫入了length個(gè)字節(jié)或者寫完了string以后,寫入就會(huì)停止,視乎先碰到哪種情況。fwrite()返回寫入的字符數(shù),出現(xiàn)錯(cuò)誤時(shí)則返回FALSE。相關(guān)參考官方網(wǎng)站:文件參考三、解決方案思路:開啟ob_start緩沖,當(dāng)已經(jīng)調(diào)出數(shù)據(jù)的時(shí)候獲取ob_get_contents,然后生成靜態(tài)頁,ob_end_clean清除緩沖?ok,就這么來,來看一個(gè)例子(php+mysql的結(jié)合):創(chuàng)建數(shù)據(jù)庫:CREATETABLE'bihtml'('id'int(11)NOTNULLauto_increment,'szdtitle'varchar(16)NOTNULL,'szdcontent'textNOTNULL,PRIMARYKEY('id'))TYPE=MyISAM;獲取當(dāng)前的ID,并導(dǎo)入模板:四、說明事項(xiàng)1:一般建議管理員添加數(shù)據(jù)的時(shí)候就生成靜態(tài)頁面,可以考慮記錄生成的文件名次和路徑.2:php主要是ob_starts()和ob_get_contents生成靜態(tài)頁面的時(shí)候很有用,當(dāng)然也可以考慮調(diào)出數(shù)據(jù)庫直接替換模板里面的變量也是可以的.3:主要的模板使用smarty,phplib都是可以的,smarty使用比較簡(jiǎn)易.一、引論P(yáng)HR一門最近幾年興起的web設(shè)計(jì)腳本語言,由于它的強(qiáng)大和可伸縮性,近幾年來得到長足的發(fā)展,php相比傳統(tǒng)的asp網(wǎng)站,在速度上有絕對(duì)的優(yōu)勢(shì),想mssql轉(zhuǎn)6萬條數(shù)據(jù)php如需要40秒,asp不下2分鐘.但是,由于網(wǎng)站的數(shù)據(jù)越來越多,我們渴求能更快速的調(diào)用數(shù)據(jù),不必要每次都從數(shù)據(jù)庫掉,我們可以從其他的地方,比方一個(gè)文件,或者某個(gè)內(nèi)存地址,這就是php的緩存技術(shù),也就是Cache技術(shù).二、分析深入一般來說,緩存的目的是把數(shù)據(jù)放在一個(gè)地方讓訪問的更快點(diǎn),毫無疑問,內(nèi)存是最快的,但是,幾百M(fèi)的數(shù)據(jù)能往內(nèi)存放么?這不現(xiàn)實(shí),當(dāng)然,有的時(shí)候臨時(shí)放如服務(wù)器緩存,如ob_start()這個(gè)緩存頁面開啟的話在發(fā)送文件頭之前頁面內(nèi)容都被緩存在內(nèi)存中,知道等頁面輸出自動(dòng)清楚或者等待ob_get_contents的返回,或者被ob_end_clean顯示的清除,這在靜態(tài)頁面的生成中能很好的利用,在模板中能得到很好的體現(xiàn),我的這篇文章深入的討論了:談PHP生成靜態(tài)頁面,這是一種方式,但這是臨時(shí)性的,不是解決我們問題的好方法.另夕卜,在asp中有一對(duì)象application,可以保存公用的參數(shù),這也算點(diǎn)緩存,但在php,我至今沒看到開發(fā)者產(chǎn)出這種對(duì)象的確,沒必要.的頁面緩存技術(shù)就用的是viewstate,而cache就是文件關(guān)聯(lián),(不一定準(zhǔn)確),文件被修改,更新緩存,文件沒被修改而且不超時(shí)(注釋1),就讀取緩存,返回結(jié)果,就是這個(gè)思路,看看這個(gè)源碼:下面我打斷這個(gè)代碼逐行解釋.三、程序透析這個(gè)緩存類(類沒什么好怕的.請(qǐng)繼續(xù)看)名稱是cache,有2個(gè)屬性:private$cache_dir;private$expireTime=180;$cache_dir是緩存文件所放的相對(duì)網(wǎng)站目錄的父目錄,$expireTime(注釋一)是我們緩存的數(shù)據(jù)過期的時(shí)間,主要是這個(gè)思路:當(dāng)數(shù)據(jù)或者文件被加載的時(shí)候,先判斷緩存文件存在不,返回false,文件最后修改時(shí)間和緩存的時(shí)間和比當(dāng)前時(shí)間大不,大的話說明緩存還沒到期,小的話返回false,當(dāng)返回false的時(shí)候,讀取原始數(shù)據(jù),寫入緩存文件中,返回?cái)?shù)據(jù).接著看程序:function__construct($cache_dirname)(if(!@is_dir($cache_dirname))(if(!@mkdir($cache_dirname,0777)){$this->warn('緩存文件不存在而且不能創(chuàng)建,需要手動(dòng)創(chuàng)建.');returnfalse;TOC\o"1-5"\h\z}}$this->cache_dir=$cache_dirname;}當(dāng)類第一次被實(shí)例的時(shí)候構(gòu)造默認(rèn)函數(shù)帶參數(shù)緩存文件名稱,如文件不存在,創(chuàng)建一個(gè)有編輯權(quán)限的文件夾,創(chuàng)建失敗的時(shí)候拋出異常.然后把cache類的$cache_dir屬性設(shè)置為這個(gè)文件夾名稱,我們的所有緩存文件都是在這個(gè)文件夾下面的.function__destruct(){echo'Cacheclassbye.';}這是class類的析構(gòu)函數(shù),為了演示,我們輸出一個(gè)字符串表示我們釋放cache類資源成功.functionwarn($errorstring){echo"<b><fontcolor='red'>發(fā)生錯(cuò)誤:<pre>".$errorstring."</pre></font></b>";}這個(gè)方法輸出錯(cuò)誤信息.這個(gè)方法返回當(dāng)前url的信息,這是我看國外很多人的cms系統(tǒng)這樣做,主要是緩存x.php?page=1,x.php?page=2,等這種文件的,這里列出是為了擴(kuò)展的這個(gè)cache類功能的.functioncache_page($pageurl,$pagedata){if(!$fso=fopen($pageurl,'w')){$this->warns('無法打開緩存文件.');//trigger_errorreturnfalse;TOC\o"1-5"\h\z}if(!flock($fso,LOCK_EX)){//LOCK_NB排它型鎖定$this->warns('無法鎖定緩存文件.');//trigger_errorreturnfalse;}if(!fwrite($fso,$pagedata)){〃寫入字節(jié)流,serialize寫入其他格式$this->warns('無法寫入緩存文件.');//trigger_errorreturnfalse;}flock($fso,LOCK_UN);〃釋放鎖定fclose($fso);returntrue;}cache_page方法分別傳入的是緩存的文件名稱和數(shù)據(jù),這是把數(shù)據(jù)寫到文件里的方法冼用fopen打開文件,然后調(diào)用句柄鎖定這個(gè)文件,然后用fwrite寫入文件,最后釋放這個(gè)句柄,任何一步發(fā)生錯(cuò)誤將拋出錯(cuò)誤.您可能看到這個(gè)注釋:寫入字節(jié)流,serialize寫入其他格式順便一提的是如果我們要把一個(gè)數(shù)組,(可以從MySQL數(shù)據(jù)庫里面select查詢除了的結(jié)果)用serialize函數(shù)寫入,用unserialize讀取到原來的類型.functiondisplay_cache($cacheFile)(if(!file_exists($cacheFile))($this->warn('無法讀取緩存文件.');//trigger_errorreturnfalse;}echo'讀取緩存文件:'.$cacheFile;//returnunserialize(file_get_contents($cacheFile));$fso=fopen($cacheFile,'r');$data=fread($fso,filesize($cacheFile));fclose($fso);return$data;}這是由文件名稱讀取緩存的方法,直接打開文件,讀取全部,如果文件不存在的或者無法讀取的話返回false,當(dāng)然,你感到不人性的話,可以重新生成緩存.functionreadData($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="fromherewocangetitfrommysqldatabase,updatetimeis<b>".date('lTOC\o"1-5"\h\zdS\ofFYh:i:sA')."</b>,過期時(shí)間是:".date('ldS\ofFYh:i:sA',time()+$this->expireTime)."";$this->cache_page($cacheFile,$data);}return$data;}這個(gè)函數(shù)是我們調(diào)用的方法,可以寫成接口的方法,由傳入?yún)?shù)判斷文件存在不,文件最后修改時(shí)間+expireTime的時(shí)間是不是過了當(dāng)前時(shí)間(大于的話說明沒有過期),如果文件不存在或者已經(jīng)過期,重新加載原始數(shù)據(jù),這里,為了簡(jiǎn)單期間,我們是直接源是字符串,您可以把cache類繼承某類,取到數(shù)據(jù)庫的數(shù)據(jù).(注釋2)四、補(bǔ)充說明,結(jié)語注釋一:這個(gè)緩存的時(shí)間您可以自己調(diào),可以根據(jù)時(shí)間情況讀取數(shù)組,xml,緩存等,請(qǐng)按照您的方便,值得一提的是緩存的時(shí)間(也就是緩存的key)也用緩存控制,.這在cms系統(tǒng)中被廣泛使用,他們把要更新的key放在緩存中,非常容易控制全戰(zhàn).注釋二:php5開始支持類繼承,這是讓人興奮的,把網(wǎng)站全局休息寫在一個(gè)配置的類里面,再寫與數(shù)據(jù)層交互的類(如與MySQL交互的類),我們的這個(gè)cache類繼承數(shù)據(jù)交互的類,可以非常容易的讀取數(shù)據(jù)庫,這是外話,此處不再展開,有時(shí)間和大家詳談.

特別說明,這個(gè)類文件針對(duì)的php5以上版本,其他版本的請(qǐng)不要使用類.functionget_url(){if(!isset($_SERVER['REQUEST_URI'])){$url=$_SERVER['REQUEST_URI'];}else{$url=$_SERVER['SCRIPT_NAME'];$url.=(!emptyempty($_SERVER['QUERY_STRING']))$_SERVER['QUERY_STRING']:'';TOC\o"1-5"\h\z}8.return$url;}<?phpclasscache{/*ClassName:cacheDescription:controltocachedata,$cache_out_timeisaarraytosavecachedatetimeout.Version:1.0Author:老農(nóng)cjjerLastmodify:2006-2-26AuthorURL:[url][/url]*/private$cache_dir;private$expireTime=180;//緩存的時(shí)間是60秒function__construct($cache_dirname){if(!@is_dir($cache_dirname)){if(!@mkdir($cache_dirname,0777)){$this->warn('緩存文件不存在而且不能創(chuàng)建,需要手動(dòng)創(chuàng)建.');returnfalse;TOC\o"1-5"\h\z}}$this->cache_dir=$cache_dirname;}function__destruct(){echo'Cacheclassbye.';}25.functionget_url(){if(!isset($_SERVER['REQUEST_URI'])){$url=$_SERVER['REQUEST_URI'];}else{$url=$_SERVER['SCRIPT_NAME'];$url.=(!emptyempty($_SERVER['QUERY_STRING']))30.$url=$_SERVER['SCRIPT_NAME'];$url.=(!emptyempty($_SERVER['QUERY_STRING']))31.

$_SERVER['QUERY_STRING']:'';TOC\o"1-5"\h\z}33.return$url;}36.functionwarn($errorstring){echo"<b><fontcolor='red'>發(fā)生錯(cuò)誤:<pre>".$errorstring."</pre></font></b>";}40.functioncache_page($pageurl,$pagedata){if(!$fso=fopen($pageurl,'w')){$this->warns('無法打開緩存文件.');//trigger_errorreturnfalse;TOC\o"1-5"\h\z}if(!flock($fso,LOCK_EX)){//LOCK_NB排它型鎖定$this->warns('無法鎖定緩存文件.');//trigger_errorreturnfalse;}if(!fwrite($fso,$pagedata)){〃寫入字節(jié)流,serialize寫入其他格式$this->warns('無法寫入緩存文件.');//trigger_errorreturnfalse;}flock($fso,LOCK_UN);〃釋放鎖定fclose($fso);returntrue;}1.$this->warn('無法讀取緩存文件.');//trigger_errorreturnfalse;}echo'讀取緩存文件:'.$cacheFile;//returnunserialize(file_get_contents($cacheFile));$fso=fopen($cacheFile,'r');$data=fread($fso,filesize($cacheFile));fclose($fso);return$data;}functionreadData($cacheFile='default_cache.txt'){$cacheFile=$this->cache_dir."/".$cacheFile;if(file_exists($cacheFile)&&filemtime($cacheFile)>(time()-$this->expireTime)){

$data=$this->display_cache($cacheFile);}else{timeisYh:i:s$data="fromherewocangetitfrommysqldatabase,updateTOC\o"1-5"\h\z<b>".date('l

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論