一、引論
PHP,一門最近幾年興起的web設計腳本語言,由於它的強大和可伸縮性,近幾年來得到長足的發展,php相比傳統的asp網站,在速度上有絕對的優勢,想mssql轉6萬條資料php如需要40秒,asp不下2分鐘.但是,由於網站的資料越來越多,我們渴求能更快速的呼叫資料,不必要每次都從資料庫掉,我們可以從其他的地方,比方一個檔案,或者某個記憶體位址,這就是php的快取技術,也就是Cache技術.
二、分析深入
一般來說,快取的目的是把資料放在一個地方讓訪問的更快點,毫無疑問,內存是最快的,但是,幾百M的數據能往內存放麼?這不現實,當然,有的時候臨時放如服務器緩存,如ob_start( )這個快取頁面開啟的話在發送文件頭之前頁面內容都被緩存在內存中,知道等頁面輸出自動清楚或者等待ob_get_contents的返回,或者被ob_end_clean顯示的清除,這在靜態頁面的生成中能很好的利用,在模板中能得到很好的體現,這是一種方式,但這是臨時性的,不是解決我們問題的好方法.
另外,在asp中有一對象application,可以保存公用的參數,這也算點快取,但在php,我至今沒看到開發者產出這種物件,的確,沒必要. asp.net的頁面快取技術就用的是viewstate,而cache就是檔案關聯,(不一定準確),檔案被修改,更新快取,檔案沒被修改而且不逾時(註解1),就讀取快取,回傳結果,就是這個想法,看看這個原始碼:
PHP:[Copy to clipboard]
class cache{
/*
Class Name: cache
Description: control to cache data,$cache_out_time is a array to save cache date time out.
Version: 1.0@ 5% - 2-26
Author URL: http://www.cjjer.com
*/
private $cache_dir;
private $expireTime=180;//快取的時間是60 秒
function _construct($ !@is_dir($cache_dirname)){
if(!@mkdir($cache_dirname,0777)){
$this->warn('快取檔案不存在而且不能建立,需要手動建立.');
re
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 .= (! )) ? '?' . $_SERVER['QUERY_STRING'] : '';
}
return $url;
}
function warn($errorstring){
>發生錯誤:
".$errorstring."
";
}
function cache_page($pageurl,$pagedata){
if(!$fso=fopen( $pageurl,'w')){
$this->warns('無法開啟快取檔案.');//trigger_error
return false;
}
if(!flock($fso,LOCK_EX)){//LOCK_NB//LOCK_NB ,排它型鎖定
$this->warns('無法鎖定快取檔案.');//trigger_error
return false;
}
if(!fwrite($fso,$pagedata)){//寫入位元組串流,serialize寫入其他格式
$this->warns('無法寫入快取檔案.');//trigger_error
return false;
}
flock($fso,LOCK_UN);//釋放鎖定 fso);
return true;
}
function display_cache($cacheFile){
if(!file_exists($cacheFile)){
$this->warn(!file_exists($cacheFile)){
$this->warn(!file_exists($cacheFile)){
$this->warn('無法讀取快取檔案. return false;
}
echo '讀取快取檔案:'.$cacheFile;
//return unserialize(file_get_contents($cacheFile));
$fso = fopen($cacheFile, 'r'); 資料> ($fso, filesize($cacheFile));
fclose($fso);
return $data;
}
function readData($cacheFile='default_cache.$ "/".$cacheFile;
if(file_exists($cacheFile)&&filemtime($cacheFile)>(time()-$this->expireTime)){
$data=$this->display_cache($cacheFile);
$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;
}
}
?>
下面我打斷這個代碼逐行解釋.
三、程序透析
下面我打斷這個代碼逐行解釋.
類
三程序透析
名稱是cache,有2個屬性:
CODE:[Copy to clipboard]private $cache_dir;
private $expireTime=180;
$cache_dir是緩存檔案所放的相對網站目錄的父筆註解目錄一)是我們快取的資料過期的時間,主要是這個思路:
當資料或檔案被載入的時候,先判斷快取檔案存在不,回傳false ,檔案最後修改時間和快取的時間和比目前時間大不,大的話說明快取還沒到期,小的話回傳false,當回傳false的時候,讀取原始資料,寫入快取檔案,回傳資料.
接著看程式:
PHP:[Copy to clipboard ]
function __construct($cache_dirname){
if(!@is_dir($cache_dirname)){
if(!@mkdir($cache_dirname,0777)){
' ,需手動建立.');
return false;
}
}
$this->cache_dir = $cache_dirname;
}
帶如檔案不存在,建立一個有編輯權限的資料夾,建立失敗的時候拋出異常.然後把cache類別的$cache_dir屬性設定為這個資料夾名稱,我們的所有快取檔案都是在這個資料夾下面的.
PHP:[Copy to clipboard]
function __destruct(){
echo 'Cache class bye.';
}
的示範我們釋放cache類資源成功.
PHP:[Copy to clipboard]
function warn($errorstring){
echo "
出錯:".$errorstring. "
";
}
這個方法輸出錯誤訊息.
PHP:[Copy to clipboard]
function get_url() { _SERVER['REQUEST_URI'])) {
$url = $_SERVER['REQUEST_URI'];
}else{
$url = $_SERVER['SCRIPT_NAME'] QUERY_STRING'])) ? '?' . $_SERVER['QUERY_STRING'] : '';
}
return $url;
}
這個方法返回這個方法嗎?的cms系統這樣做,主要是快取x.php?page=1,x.php?page=2,等這種檔案的,這裡列出是為了擴充的這個cache類別功能的.
PHP:[ Copy to clipboard]
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('無法鎖定快取檔案.');//triggerdor false;
}
if(!fwrite($fso,$pagedata)){//寫入位元組流,serialize寫入其他格式
$this->warns('無法寫入快取檔案.');// trigger_error
return false;
}
flock($fso,LOCK_UN);//釋放鎖定
fclose($fso);
return true;
fclose($fso);
return true;
} ,這是把資料寫到檔案裡的方法,先用fopen開啟檔案,然後呼叫句柄鎖定這個檔案,然後用fwrite寫入檔案,最後釋放這個句柄,任何一步發生錯誤將會拋出錯誤. 您可能看到這個註解:
寫入位元組流,serialize寫入其他格式
順便一提的是如果我們要把一個陣列,(可以從MySQL資料庫裡面select查詢除了的結果)用serialize函數寫入,用unserialize讀取到原來的型別.
PHP:[Copy to clipboard]
function display_cache($cacheFile){
if(!file_exists($cacheFile)){
if(!file_exists($cacheFile)){
$this->warn($ );//trigger_error
return false;
}
echo '讀取快取檔案:'.$cacheFile;
//return unserialize(file_get_contents($cacheFile));
, fopen
, ;
$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類別繼承某類別,取到資料庫的資料.(註解2)
四、補充說明,結語
註解一:這個快取的時間您可以自己調,可以根據時間狀況讀取陣列,xml ,快取等,請按照您的方便,值得一提的是緩存的時間(也就是緩存的key)也用緩存控制,.這在cms系統中被廣泛使用,他們把要更新的key放在緩存中,非常容易控制全戰.
註釋二:php5開始支援類別繼承,這是讓人興奮的,把網站全局休息寫在一個配置的類別裡面,再寫與資料層交互的類別(如與MySQL交互的類別),我們的這個cache類別繼承資料互動的類別,可以非常容易的讀取資料庫,這是外話,這裡不再展開,有時間和大家詳談.
特別說明,這個類別檔案針對的php5以上版本,其他版本的請不要使用類.更多相關內容請關注PHP中文網(www.php.cn)!