日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

詳解PHP中緩存技術(shù)的應(yīng)用_PHP教程

編輯Tag賺U幣
教程Tag:暫無(wú)Tag,歡迎添加,賺取U幣!

推薦:解析PHP 開(kāi)發(fā)中的中文編碼問(wèn)題
PHP程序設(shè)計(jì)中中文編碼問(wèn)題曾經(jīng)困擾很多人,導(dǎo)致這個(gè)問(wèn)題的原因其實(shí)很簡(jiǎn)單,每個(gè)國(guó)家(或區(qū)域)都規(guī)定了計(jì)算機(jī)信息交換用的字符編碼集,如美國(guó)的擴(kuò)展 ASCII 碼, 中國(guó)的 GB2312-80,日本的 JIS 等。作為該國(guó)家/區(qū)域內(nèi)信息處理的基礎(chǔ),字符編碼集起著統(tǒng)一編碼的

PHP,一門(mén)最近幾年興起的web設(shè)計(jì)腳本語(yǔ)言,由于它的強(qiáng)大和可伸縮性,近幾年來(lái)得到長(zhǎng)足的發(fā)展,php相比傳統(tǒng)的asp網(wǎng)站,在速度上有絕對(duì)的優(yōu)勢(shì),想mssql轉(zhuǎn)6萬(wàn)條數(shù)據(jù)php如需要40秒,asp不下2分鐘.但是,由于網(wǎng)站的數(shù)據(jù)越來(lái)越多,我們渴求能更快速的調(diào)用數(shù)據(jù),不必要每次都從數(shù)據(jù)庫(kù)掉,我們可以從其他的地方,比方一個(gè)文件,或者某個(gè)內(nèi)存地址,這就是php的緩存技術(shù),也就是Cache技術(shù).


一般來(lái)說(shuō),緩存的目的是把數(shù)據(jù)放在一個(gè)地方讓訪(fǎng)問(wèn)的更快點(diǎn),毫無(wú)疑問(wèn),內(nèi)存是最快的,但是,幾百M(fèi)的數(shù)據(jù)能往內(nèi)存放么?這不現(xiàn)實(shí),當(dāng)然,有的時(shí)候臨時(shí)放如服務(wù)器緩存,如ob_start()這個(gè)緩存頁(yè)面開(kāi)啟的話(huà)在發(fā)送文件頭之前頁(yè)面內(nèi)容都被緩存在內(nèi)存中,知道等頁(yè)面輸出自動(dòng)清楚或者等待ob_get_contents的返回,[或者被ob_end_clean顯示的清除,這在靜態(tài)頁(yè)面的生成中能很好的利用,在模板中能得到很好的體現(xiàn),我的這篇文章深入的討論了:

談PHP生成靜態(tài)頁(yè)面,這是一種方式,但這是臨時(shí)性的,不是解決我們問(wèn)題的好方法.

另外,在asp中有一對(duì)象application,可以保存公用的參數(shù),這也算點(diǎn)緩存,但在php,我至今沒(méi)看到開(kāi)發(fā)者產(chǎn)出這種對(duì)象,的確,沒(méi)必要.asp.net的頁(yè)面緩存技術(shù)就用的是viewstate,而cache就是文件關(guān)聯(lián),(不一定準(zhǔn)確),文件被修改,更新緩存,文件沒(méi)被修改而且不超時(shí)(注釋1),就讀取緩存,返回結(jié)果,就是這個(gè)思路,看看這個(gè)源碼:

<?php
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
Author: 老農(nóng) cjjer
Last modify:2006-2-26
Author URL: http://www.cjjer.com
*/
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)建.');
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 "<b><font color='red'>發(fā)生錯(cuò)誤:<pre>".errorstring."</pre></font></b>";
}

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

function display_cache(cacheFile){
if(!file_exists(cacheFile)){
this->warn('無(wú)法讀取緩存文件.');//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 <b>".date('l dS \of F Y h:i:s A')."</b>,過(guò)期時(shí)間是:".date('l dS \of F Y h:i:s A',time()+this->expireTime)."----------";
this->cache_page(cacheFile,data);
}
return data;
}



}
?>

下面我打斷這個(gè)代碼逐行解釋.
三:程序透析

這個(gè)緩存類(lèi)(類(lèi)沒(méi)什么好怕的.請(qǐng)繼續(xù)看)名稱(chēng)是cache,有2個(gè)屬性:
 

private cache_dir;
private expireTime=180;
 

cache_dir是緩存文件所放的相對(duì)網(wǎng)站目錄的父目錄, expireTime(注釋一)是我們緩存的數(shù)據(jù)過(guò)期的時(shí)間,主要是這個(gè)思路:
當(dāng)數(shù)據(jù)或者文件被加載的時(shí)候,先判斷緩存文件存在不,返回false ,文件最后修改時(shí)間和緩存的時(shí)間和比當(dāng)前時(shí)間大不,大的話(huà)說(shuō)明緩存還沒(méi)到期,小的話(huà)返回false,當(dāng)返回false的時(shí)候,讀取原始數(shù)據(jù),寫(xiě)入緩存文件中,返回?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)建.');
return false;
}
}
this->cache_dir = cache_dirname;
}

當(dāng)類(lèi)第一次被實(shí)例的時(shí)候構(gòu)造默認(rèn)函數(shù)帶參數(shù)緩存文件名稱(chēng),如文件不存在,創(chuàng)建一個(gè)有編輯權(quán)限的文件夾,創(chuàng)建失敗的時(shí)候拋出異常.然后把cache類(lèi)的 cache_dir屬性設(shè)置為這個(gè)文件夾名稱(chēng),我們的所有緩存文件都是在這個(gè)文件夾下面的.

 

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

這是class類(lèi)的析構(gòu)函數(shù),為了演示,我們輸出一個(gè)字符串表示我們釋放cache類(lèi)資源成功.
 

function warn(errorstring){
echo "<b><font color='red'>發(fā)生錯(cuò)誤:<pre>".errorstring."</pre></font></b>";
}
 

這個(gè)方法輸出錯(cuò)誤信息.

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;
}

這個(gè)方法返回當(dāng)前url的信息,這是我看國(guó)外很多人的cms系統(tǒng)這樣做,主要是緩存x.php?page=1,x.php?page=2,等這種文件的,這里列出是為了擴(kuò)展的這個(gè)cache類(lèi)功能的.

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

cache_page方法分別傳入的是緩存的文件名稱(chēng)和數(shù)據(jù),這是把數(shù)據(jù)寫(xiě)到文件里的方法,先用fopen打開(kāi)文件,然后調(diào)用句柄鎖定這個(gè)文件,然后用fwrite寫(xiě)入文件,最后釋放這個(gè)句柄,任何一步發(fā)生錯(cuò)誤將拋出錯(cuò)誤. 您可能看到 這個(gè)注釋
寫(xiě)入字節(jié)流,serialize寫(xiě)入其他格式
,順便一提的是如果我們要把一個(gè)數(shù)組,(可以從MySQL數(shù)據(jù)庫(kù)里面select查詢(xún)除了的結(jié)果)用serialize函數(shù)寫(xiě)入,用unserialize讀取到原來(lái)的類(lèi)型.


function display_cache(cacheFile){
if(!file_exists(cacheFile)){
this->warn('無(wú)法讀取緩存文件.');//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;
}
 

這是由文件名稱(chēng)讀取緩存的方法,直接打開(kāi)文件,讀取全部,如果文件不存在的或者無(wú)法讀取的話(huà)返回false,當(dāng)然,你感到不人性的話(huà),可以重新生成緩存.

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 <b>".date('l dS \of F Y h:i:s A')."</b>,過(guò)期時(shí)間是:".date('l dS \of F Y h:i:s A',time()+this->expireTime)."----------";
this->cache_page(cacheFile,data);
}
return data;
}

這個(gè)函數(shù)是我們調(diào)用的方法,可以寫(xiě)成接口的方法,由傳入?yún)?shù)判斷文件存在不,文件最后修改時(shí)間+expireTime的時(shí)間是不是過(guò)了當(dāng)前時(shí)間(大于的話(huà)說(shuō)明沒(méi)有過(guò)期),如果文件不存在或者已經(jīng)過(guò)期,重新加載原始數(shù)據(jù),這里,為了簡(jiǎn)單期間,我們是直接源是字符串,您可以把cache類(lèi)繼承某類(lèi),取到數(shù)據(jù)庫(kù)的數(shù)據(jù).(注釋2)

四:補(bǔ)充說(shuō)明,結(jié)語(yǔ)

注釋一 :這個(gè)緩存的時(shí)間您可以自己調(diào),可以根據(jù)時(shí)間情況讀取數(shù)組,xml,緩存等,請(qǐng)按照您的方便,值得一提的是緩存的時(shí)間(也就是緩存的key)也用緩存控制,.這在cms系統(tǒng)中被廣泛使用,他們把要更新的key放在緩存中,非常容易控制全戰(zhàn).

注釋二: php5開(kāi)始支持類(lèi)繼承,這是讓人興奮的,把網(wǎng)站全局休息寫(xiě)在一個(gè)配置的類(lèi)里面,再寫(xiě)與數(shù)據(jù)層交互的類(lèi)(如與MySQL交互的類(lèi)),我們的這個(gè)cache類(lèi)繼承數(shù)據(jù)交互的類(lèi),可以非常容易的讀取數(shù)據(jù)庫(kù),這是外話(huà),此處不再展開(kāi),有時(shí)間和大家詳談.

特別說(shuō)明,這個(gè)類(lèi)文件針對(duì)的php5以上版本,其他版本的請(qǐng)不要使用類(lèi).
 

分享:Windows IIS環(huán)境下安裝和配置PHP開(kāi)發(fā)環(huán)境
一、首先把php的壓縮包(這里以PHP4.3.2為例)解壓到C:\php-4.3.2-Win32目錄中,然后從其中找到一個(gè)叫php.ini-recommended的文件,把他更名為php.ini。 二、打開(kāi)該文件,找到extension_dir = ./ ,將其改為 extension_dir = C:\php-4.3.2-Win32\extensions

來(lái)源:模板無(wú)憂(yōu)//所屬分類(lèi):PHP教程/更新時(shí)間:2010-05-26
相關(guān)PHP教程