PHP,一門最近幾年興起的web設計腳本語言,由於它的強大和可伸縮性,近幾年來得到長足的發展,php相比傳統的asp網站,在速度上有絕對的優勢,想mssql轉6萬條數據php如需要40秒,asp不下2分鐘.但是,由於網站的數據越來越多,我們渴求能更快速的調用數據,不必要每次都從資料庫掉,我們可以從其
PHP,一門最近幾年興起的web設計腳本語言,由於它的強大和可伸縮性,近幾年來得到長足的發展,php相比傳統的asp網站,在速度上有絕對的優勢,想mssql轉6萬條數據php如需要40秒,asp不下2分鐘.但是,由於網站的數據越來越多,我們渴求能更快速的調用數據,不必要每次都從資料庫掉,我們可以從其他的地方,比方一個文件,或者某個記憶體地址,這就是php的緩存技術,也就是Cache技術.
一般來說,緩存的目的是把數據放在一個地方讓訪問的更快點,毫無疑問,記憶體是最快的,但是,幾百M的數據能往記憶體放麽?這不現實,當然,有的時候臨時放如伺服器緩存,如ob_start()這個緩存頁面開啟的話在發送文件頭之前頁面內容都被緩存在記憶體中,知道等頁面輸出自動清楚或者等待ob_get_contents的返回,[或者被ob_end_clean顯示的清除,這在靜態頁面的生成中能很好的利用,在模板中能得到很好的體現,我的這篇文章深入的討論了:
談PHP生成靜態頁面,這是一種方式,但這是臨時性的,不是解決我們問題的好方法.
另外,在asp中有一對象application,可以保存公用的參數,這也算點緩存,但在php,我至今沒看到開發者產出這種對象,的確,沒必要.asp.net的頁面緩存技術就用的是viewstate,而cache就是文件關聯,(不一定准確),文件被修改,更新緩存,文件沒被修改而且不超時(註釋1),就讀取緩存,返回結果,就是這個思路,看看這個源碼:
<?php } |
下麵我打斷這個代碼逐行解釋.
三:程式透析
這個緩存類(類沒什麼好怕的.請繼續看)名稱是cache,有2個屬性:
private$cache_dir; private$expireTime=180; |
$cache_dir是緩存文件所放的相對網站目錄的父目錄,$expireTime(註釋一)是我們緩存的數據過期的時間,主要是這個思路:
當數據或者文件被載入的時候,先判斷緩存文件存在不,返回false,文件最後修改時間和緩存的時間和比當前時間大不,大的話說明緩存還沒到期,小的話返回false,當返回false的時候,讀取原始數據,寫入緩存文件中,返回數據.,
接著看程式:
function__construct($cache_dirname){ if(!@is_dir($cache_dirname)){ if(!@mkdir($cache_dirname,0777)){ $this->warn(''緩存文件不存在而且不能創建,需要手動創建.''); returnfalse; } } $this->cache_dir=$cache_dirname; } |
當類第一次被實例的時候構造預設函數帶參數緩存文件名稱,如文件不存在,創建一個有編輯許可權的文件夾,創建失敗的時候拋出異常.然後把cache類的$cache_dir屬性設置為這個文件夾名稱,我們的所有緩存文件都是在這個文件夾下麵的.
function__destruct(){ echo''Cacheclassbye.''; } |
這是class類的析構函數,為了演示,我們輸出一個字元串表示我們釋放cache類資源成功.
functionwarn($errorstring){ |
這個方法輸出錯誤信息.
functionget_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類功能的.
functioncache_page($pageurl,$pagedata){ if(!$fso=fopen($pageurl,''w'')){ $this->warns(''無法打開緩存文件.'');//trigger_error returnfalse; } if(!flock($fso,LOCK_EX)){//LOCK_NB,排它型鎖定 $this->warns(''無法鎖定緩存文件.'');//trigger_error returnfalse; } if(!fwrite($fso,$pagedata)){//寫入位元組流,serialize寫入其他格式 $this->warns(''無法寫入緩存文件.'');//trigger_error returnfalse; } flock($fso,LOCK_UN);//釋放鎖定 fclose($fso); returntrue; } |
cache_page方法分別傳入的是緩存的文件名稱和數據,這是把數據寫到文件里的方法,先用fopen打開文件,然後調用句柄鎖定這個文件,然後用fwrite寫入文件,最後釋放這個句柄,任何一步發生錯誤將拋出錯誤.您可能看到這個註釋
寫入位元組流,serialize寫入其他格式
,順便一提的是如果我們要把一個數組,(可以從MySQL資料庫裡面select查詢除了的結果)用serialize函數寫入,用unserialize讀取到原來的類型.
functiondisplay_cache($cacheFile){ if(!file_exists($cacheFile)){ $this->warn(''無法讀取緩存文件.'');//trigger_error returnfalse; } echo''讀取緩存文件:''.$cacheFile; //returnunserialize(file_get_contents($cacheFile)); $fso=fopen($cacheFile,''r''); $data=fread($fso,filesize($cacheFile)); fclose($fso); return$data; } |
這是由文件名稱讀取緩存的方法,直接打開文件,讀取全部,如果文件不存在的或者無法讀取的話返回false,當然,你感到不人性的話,可以重新生成緩存.
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(''ldSofFYh:i:sA'')."</b>,過期時間是:".date(''ldSofFYh:i:sA'',time()+$this->expireTime)."----------"; $this->cache_page($cacheFile,$data); } return$data; } |
這個函數是我們調用的方法,可以寫成介面的方法,由傳入參數判斷文件存在不,文件最後修改時間+expireTime的時間是不是過了當前時間(大於的話說明沒有過期),如果文件不存在或者已經過期,重新載入原始數據,這裡,為了簡單期間,我們是直接源是字元串,您可以把cache類繼承某類,取到資料庫的數據.(註釋2)
四:補充說明,結語
註釋一:這個緩存的時間您可以自己調,可以根據時間情況讀取數組,xml,緩存等,請按照您的方便,值得一提的是緩存的時間(也就是緩存的key)也用緩存控制,.這在cms系統中被廣泛使用,他們把要更新的key放在緩存中,非常容易控制全戰.
註釋二:php5開始支持類繼承,這是讓人興奮的,把網站全局休息寫在一個配置的類裡面,再寫與數據層交互的類(如與MySQL交互的類),我們的這個cache類繼承數據交互的類,可以非常容易的讀取資料庫,這是外話,此處不再展開,有時間和大家詳談.
特別說明,這個類文件針對的php5以上版本,其他版本的請不要使用類.
轉載自:http://www.aspnetjia.com