天天看點

PHP緩存技術介紹!

a:

為什麼要使用緩存技術?理由很簡單:提高效率。在程式開發中,擷取資訊的方式主要是查詢資料庫,除此以外,也可能是通過Web Services或者别的某種方法,無論哪種方法,在大量的并發通路面前,它們都可能成為效率的瓶頸,為了解決這些問題,人們提出了很多解決方案,其中一 些是利用優化軟體(如:APC,Eaccelerator,Zend Optimizer等等)來提高程式的運作效率,合理的運用這些軟體,往往能使程式的運作效率得到數量級上的提升,但前提是你必須擁主機的控制權,以便能 夠安裝這些軟體,如果你使用的是虛拟主機的話,那麼隻能祈禱你的服務提供商已經預裝了某個優化軟體,否則就必須自己使用PHP來實作相應的緩存功能。如果 這讓你感到無所适從,相信下面的文字能給你一些啟發。

很多PHP程式員都使用Adodb+Smarty這樣的黃金搭檔,那麼就先看看如何使用它們的緩存功能。

首先看看adodb提供的資料緩存功能:

<?php

include('adodb.inc.php'); # load code common to ADOdb

$ADODB_CACHE_DIR = '/usr/ADODB_cache';

$conn = &ADONewConnection('mysql');  # create a connection

$conn->PConnect('localhost','userid','','agora');# connect to MySQL, agora db

$sql = 'select CustomerName, CustomerID from customers';

$rs = $conn->CacheExecute(15,$sql);

?>

如上,每次查詢資料的時候,會把相應的結果序列化後儲存到檔案中,以後同樣的查詢語句就可以不用直接查詢資料庫,而是從緩存檔案中獲得。

再來看看Smarty提供的頁面緩存功能:

<?php

require('Smarty.class.php');

$smarty = new Smarty;

$smarty->caching = true;

if(!$smarty->is_cached('index.tpl')) {

    // No cache available, do variable assignments here.

    $contents = get_database_contents();

    $smarty->assign($contents);

}

$smarty->display('index.tpl');

?>

如上,每次通路頁面的時候,都會先檢 測相應的緩存是否存在,如果不存在,就連接配接資料庫,得到資料,完成模闆變量的指派,顯示頁面,同時生成緩存檔案,這樣下次通路的時候緩存檔案就發揮作用 了,而不會再執行if塊的資料查詢語句了。當然,在實際使用中會有很多東西要考慮,比如,有效期的設定,緩存組的設定等等,具體可以檢視Smarty手冊 中有關緩存(caching)的相關章節。

以上兩個PHP流行元件緩存方式的側重點是不同的,對于Adodb的緩存而言,它緩存的是資料,對于Smarty的緩存而言,它緩存的是頁面。其他提供緩存功能的元件還有很多(如:PEAR::Cache_Lite等等),實際程式設計中使用哪個方案要具體情況具體分析,也可能會綜合使用。

使用這些元件内置的緩存方案有一個很 明顯的好處是它們的實作對用戶端而言都很透明。隻要進行必要的設定(如:緩存時間,緩存目錄等等)就可以了,而不用過多考慮實作緩存的細節問題,系統會根 據設定自動管理緩存。但是其缺點也同樣明顯,因為每次請求仍然要用PHP解析一遍,效率和純靜态相比還是大打折扣,在大的PV面前還是不能滿足要求,在這 種情況下,僅僅做動态緩存就不夠了,必須實作靜态緩存。

b:

<?php

function cache_isvalid($cacheid,$expire=300) {

@clearstatcache();

if ([email protected]_exists($cacheid)) return false;

if (!([email protected]($cacheid))) return false;

$nowtime=mktime();

if (($mtime+$expire)<$nowtime) {

return false;

}else{

return true;

}

}

function cache_write($cacheid,$cachecontent) {

$retry=100;

for ($i=0;$i<$retry;$i++) {

[email protected]($cacheid,"wb");

if ($ft!=false) break;

if ($i==($retry-1)) return false;

}

@flock($ft,LOCK_UN);

@flock($ft,LOCK_EX|LOCK_NB);

for ($i=0;$i<$retry;$i++) {

[email protected]($ft,$cachecontent);

if ($tmp!=false) break;

if ($i==($retry-1)) return false;

}

@flock($ft,LOCK_UN);

@fclose($ft);

@chmod($cacheid,0777);

return true;

}

function cache_fetch($cacheid) {

$retry=100;

for ($i=0;$i<$retry;$i++) {

[email protected]($cacheid,"rb");

if ($ft!=false) break;

if ($i==($retry-1)) return false;

}

$cachecontent='';

while ([email protected]($ft)) {

[email protected]($ft,4096);

}

@fclose($ft);

return $cachecontent;

}

function cache_clear_expired($cachedirname,$expire=300) {

[email protected]($cachedirname);

while (false!==([email protected]($cachedir))) {

if ($userfile!="." and $userfile!=".." and substr($userfile,-4,4)=='.htm') {

$cacheid=$cachedirname.'/'.$userfile;

if (!cache_isvalid($cacheid,$expire)) @unlink($cacheid);

}

}

@closedir($cachedir);

}

?>