久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

PHP 程序加速探索

 滄海九粟 2007-07-12
 
(一)簡(jiǎn)介
 
  本文嘗試對(duì)PHP程序加速的各個(gè)方面進(jìn)行探索,,包括必要性以及從不同角度采取的具體措施,。希望有助于讀者了解PHP程序加速,并應(yīng)用于實(shí)際,。
 
(二)是否需要加速,?
 
  這個(gè)問(wèn)題聽(tīng)起來(lái)有點(diǎn)愚蠢。在這個(gè)時(shí)代,,很少有人會(huì)懷疑時(shí)間是最寶貴的財(cái)富,,尤其是在商業(yè)市場(chǎng)上。程序執(zhí)行越快,,用戶就節(jié)約越多的時(shí)間,,這樣你的程序就可以用更少的時(shí)間和服務(wù)器資源為用戶服務(wù),從而產(chǎn)生更多效益,。
我想對(duì)于大部份人(包括我自己)來(lái)說(shuō),,很多WEB項(xiàng)目都是在很緊張的時(shí)間里完成的,通常沒(méi)有經(jīng)過(guò)縝密的思考和嚴(yán)格的測(cè)試,。當(dāng)開(kāi)始一個(gè)新的WEB項(xiàng)目,。很多人都在構(gòu)建那種“快而亂”的應(yīng)用,缺乏必要的時(shí)間來(lái)調(diào)整和改良代碼,,這時(shí)優(yōu)化和加速就是我們必須采取的措施,。
  然而需要特別指出的是,并不是所有程序都需要加速,。
  優(yōu)化已完成的代碼是很浪費(fèi)時(shí)間的,,最好的方法是在寫(xiě)代碼的時(shí)候就注意到效率,然后完成項(xiàng)目后只優(yōu)化確實(shí)需要優(yōu)化的那部份,。一般一個(gè)程序只會(huì)有少數(shù)幾個(gè)影響速度的瓶頸,,將它們找出來(lái)并解決掉,,程序就可以很好地運(yùn)行。另外,,當(dāng)遇到執(zhí)行效率低下的情況,,首先要用大局的眼光來(lái)找出影響效率的主要因素,而不要拘泥于細(xì)節(jié)—例如數(shù)據(jù)量過(guò)大,,服務(wù)器帶寬不夠,或硬件配置過(guò)低,,在這樣的情況下,,優(yōu)化代碼于事無(wú)補(bǔ)。
  另外,,在沒(méi)有發(fā)現(xiàn)程序有明顯的執(zhí)行緩慢的跡象時(shí),,就不要太吹毛求疵,為了改進(jìn)一些非常細(xì)節(jié)的代碼而浪費(fèi)時(shí)間,。用這些時(shí)間,,你可以完成另一個(gè)項(xiàng)目或?yàn)樵瓉?lái)的項(xiàng)目完成一個(gè)擴(kuò)展功能。當(dāng)然你可以笑話我不夠負(fù)責(zé),,沒(méi)有把工作做得盡善盡好,,我也可以說(shuō)你是完美主義者:-)  
  綜上,在你決定為你的PHP程序提速之前,,問(wèn)問(wèn)自己是否有必要,。
 
(三)如何加速?
 
要回答“如何加速”這個(gè)問(wèn)題前,,需要先回答以下兩個(gè)小問(wèn)題:
  1. 你的程序慢在哪一部份,?
  2. PHP可以從哪幾個(gè)方面考慮加速?
  第一個(gè)小問(wèn)題顯然我無(wú)法給你答案,,但我建議你用“測(cè)試腳本執(zhí)行速度”的方法來(lái)解決,。只有找出限制速度的瓶頸,才能考慮如何去解決,。
  第二個(gè)小問(wèn)題我大概的答案是:代碼優(yōu)化,,壓縮輸出,內(nèi)容緩存輸出,,函數(shù)緩存輸出,,加速/緩存工具軟件。如果你知道更多請(qǐng)告訴我:-)
  下面我們來(lái)詳細(xì)地研究一下這幾個(gè)方面的相關(guān)技術(shù),。當(dāng)然實(shí)際上每個(gè)方面都有無(wú)數(shù)的細(xì)節(jié)可以討論,,下面的內(nèi)容難免會(huì)有片面的地方,歡迎補(bǔ)充,。
 
<1> 測(cè)試
服務(wù)器負(fù)載測(cè)試

  服務(wù)器負(fù)載太大而影響程序效率也是很常見(jiàn)的,,我們需要對(duì)此進(jìn)行測(cè)試,。這里我以目前最常用的Apache服務(wù)器為例。
  Apache服務(wù)器自帶有一個(gè)叫AB(ApacheBench)的工具,,在bin目錄下,。使用這個(gè)輕巧的工具我們可以對(duì)服務(wù)器進(jìn)行負(fù)載測(cè)試,看看在重負(fù)荷之下服務(wù)器的表現(xiàn)如何,。ApacheBench 可以針對(duì)某個(gè)特定的 URL 仿真出連續(xù)的聯(lián)機(jī)請(qǐng)求,,同時(shí)還可以仿真出同時(shí)間點(diǎn)數(shù)個(gè)相同的聯(lián)機(jī)請(qǐng)求,因此利用 ApacheBench 可幫助我們?cè)诰W(wǎng)站開(kāi)發(fā)期間仿真實(shí)際上線可能的情況,,利用仿真出來(lái)的數(shù)據(jù)作為調(diào)整服務(wù)器設(shè)定或程序的依據(jù),。
  在命令行下輸出:
 
./ab -n number_of_total_requests \
-c number_of_simultaneous_requests \
http://your_web_server/your_php_app.php
 
例如:
 
./ab -n 1000 -c 50 http://www./myapp.php
 
  AB將同時(shí)向http://www./myapp.php發(fā)出50個(gè)并發(fā)請(qǐng)求,共發(fā)出1000次,。
  測(cè)試結(jié)果將可能是這樣的:
 
Server Software: Apache/2.0.16
Server Hostname: localhost
Server Port: 80
Document Path: /myapp.php
Document Length: 1311 bytes
Concurrency Level: 50
Time taken for tests: 8.794 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 1754000 bytes
HTML transferred: 1311000 bytes
Requests per second: 113.71
Transfer rate: 199.45 kb/s received
Connection Times (ms)
min avg max
Connect: 0 0 5
Processing: 111 427 550
Total: 111 427 555
 
  myapp.php每秒鐘可以處理的請(qǐng)求數(shù)為113.71個(gè),。將請(qǐng)求數(shù)增加,看看服務(wù)器能否處理更大的壓力,。你也需要調(diào)節(jié)Apache的MaxClients, ThreadsPerChild, MaxThreadsPerChild 等參數(shù),,基于你的 httpd.conf 中的 MPM 模塊選擇。
  如果你想得到更詳細(xì)的信息,,請(qǐng)到www.上查閱一些更深入的文檔,,包括模塊和第三方的提高效率的工具。修改httpd.conf后,,要重啟Apache服務(wù)器,,然后再用AB測(cè)試。你會(huì)看到每秒請(qǐng)求數(shù)增加或減少,。
  記下每次的參數(shù),,最后選擇最佳效率的那種配置。
  要指出的是,,除了AB,,還有許多優(yōu)秀的服務(wù)器性能測(cè)試軟件。另外,,如果你的服務(wù)器不是 Apache,,請(qǐng)自行尋找測(cè)試方法。
 
腳本執(zhí)行速度測(cè)試
 
  前面有提到,,只有找到影響速度的代碼,,我們才有可能進(jìn)行優(yōu)化。PEAR的benchmark包中的Benchmark_Timer類和Benchmark_Iterate類,,可以用來(lái)很方便地測(cè)試腳本執(zhí)行的速度,。(關(guān)于PEAR的安裝與配置請(qǐng)自行查看相關(guān)資料)
首先用Benchmark_Iterate類來(lái)測(cè)試程序中某個(gè)函數(shù)或類的某個(gè)方法的執(zhí)行時(shí)間。
 
benchmark1.php

<?php

require_once(‘Benchmark/Iterate.php‘);
$benchmark = new Benchmark_Iterate();

$benchmark->run(10, ‘myFunction‘,‘test‘);
$result = $benchmark->get();
echo
"

"
; print_r($result); echo "
"
;
exit;

function
myFunction($var) {
    
// do something
    
echo ‘Hello ‘;
}

?>
 
  建立benchmark Iterate對(duì)象$benchmark,,這個(gè)對(duì)象用來(lái)執(zhí)行myFunction函數(shù)10次,。
  $argument變量每次都傳遞給myFunction. 多次運(yùn)行的分析結(jié)果存入$result,,然后用benchmark對(duì)象的get()方法來(lái)獲取。這個(gè)結(jié)果用print_r()輸出到屏幕,。通常會(huì)輸出這樣的結(jié)果:
  Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello
Array(
    [1] => 0.000427
    [2] => 0.000079
    [3] => 0.000072
    [4] => 0.000071
    [5] => 0.000076
    [6] => 0.000070
    [7] => 0.000073
    [8] => 0.000070
    [9] => 0.000074
    [10] => 0.000072
    [mean] => 0.000108
    [iterations] => 10
)
  myFunction的每次執(zhí)行,,benchmark對(duì)象都會(huì)跟蹤執(zhí)行時(shí)間。并且會(huì)計(jì)算平均的執(zhí)行時(shí)間([mean]那一行),。通過(guò)多次運(yùn)行目標(biāo)函數(shù),,你可以得到該函數(shù)的平均運(yùn)行時(shí)間。
  在實(shí)際測(cè)試中,,函數(shù)的次數(shù)應(yīng)當(dāng)至少1000次左右,,這樣可以得到較客觀的結(jié)果。
 
  現(xiàn)在我們看看另一個(gè)測(cè)試腳本運(yùn)行時(shí)間的方法--使用Benchmark_Timer類來(lái)測(cè)試一段代碼執(zhí)行所消耗的時(shí)間及這一段代碼中每次調(diào)用與下一次調(diào)用間的時(shí)間,。
 
benchmark2.php
 
<?php
require_once ‘Benchmark/Timer.php‘;
$timer = new Benchmark_Timer();
$timer->start();
$timer->setMarker(‘start_myFunction‘);

for(
$i=0; $i<10; $i++){
    
myFunction($argument);
}
$timer->setMarker(‘end_myFunction‘);
$timer->stop();
$profiling = $timer->getProfiling();

echo

Time elapsed: ‘
.
$timer->timeElapsed(‘start_myFunction‘,‘end_myFunction‘) .
;
echo

; print_r($profiling); echo
;
exit;

function
myFunction($var) {
    static
$counter = 0;
    
// do something
    
echo $counter++ . ‘ ‘;
}
?>

  首先,建立一個(gè)benchmark timer對(duì)象$timer,。然后調(diào)用start()方法,,表示開(kāi)始計(jì)時(shí)。 SetMaker()方法用來(lái)標(biāo)記要測(cè)試的代碼段,。MyFunction()函數(shù)在循環(huán)中被調(diào)用,,表示一段要執(zhí)行的代碼(當(dāng)然實(shí)際中不會(huì)這么簡(jiǎn)單)。然后再用$timer對(duì)象的setMarker()方法標(biāo)記程序執(zhí)行終點(diǎn),。分析信息用getProfiling()來(lái)獲取,。在兩個(gè)標(biāo)記間程序執(zhí)行消耗的時(shí)間用timeElapsed()方法計(jì)算出來(lái)(就像例子中的循環(huán))。最后,,用print_r()輸出信息到屏幕:
Array
(
    [0] => Array
        (
            [name] => Start
            [time] => 1085730111.27175200
            [diff] => -
            [total] => 1085730111.271752
        )
 
    [1] => Array
        (
            [name] => start_myFunction
            [time] => 1085730111.27203800
            [diff] => 0.000286
            [total] => 1085730111.272038
        )
 
    [2] => Array
        (
            [name] => end_myFunction
            [time] => 1085730111.27263200
            [diff] => 0.000594
            [total] => 1085730111.272632
        )
 
    [3] => Array
        (
            [name] => Stop
            [time] => 1085730111.27271800
            [diff] => 0.000086
            [total] => 1085730111.272718
        )
)
0 1 2 3 4 5 6 7 8 9
Time elapsed: 0.000594
 
  通過(guò)這種方法,,你可以在代碼中設(shè)置大量時(shí)間段標(biāo)記,獲取每段代碼執(zhí)行時(shí)消耗的時(shí)間,,很容易可以看出到底是哪一部份的代碼影響了整個(gè)程序的運(yùn)行效率,。然后開(kāi)始著手對(duì)這部份代碼進(jìn)行改進(jìn)。
  用以上兩種方法,,你可以找出代碼中最影響速度的部份代碼,。另外還可以用來(lái)對(duì)優(yōu)化后的代碼進(jìn)行測(cè)試,看看到底執(zhí)行速度提高了多少,。通過(guò)測(cè)試->優(yōu)化->測(cè)試->優(yōu)化 …這樣不斷循環(huán),,你可以最終確定提供最佳效率的代碼。
 
<2> 加速
 
代碼優(yōu)化
  掌握了PEAR::BenchMark,,現(xiàn)在你已經(jīng)知道如何測(cè)試你的代碼,,知道如何判斷你的代碼是快是慢,是哪一部份比較慢,。那么接下來(lái)我要說(shuō)的就是如何消滅或優(yōu)化那部份慢的代碼,。
這一點(diǎn)上我個(gè)人最主要的經(jīng)驗(yàn)只有兩點(diǎn),,一是消除錯(cuò)誤的或低效的循環(huán);二是優(yōu)化數(shù)據(jù)庫(kù)查詢語(yǔ)句,。其實(shí)還存在一些其它的優(yōu)化細(xì)節(jié),,比如“str_replace比ereg_replace快”、“echo比print快”等等,。這些我暫時(shí)都放在一邊,,稍后我會(huì)提到用緩存來(lái)對(duì)付過(guò)于頻繁的IO。
下面我們將三個(gè)功能相同,,但程序?qū)懛ú煌暮瘮?shù)的效率(消耗的時(shí)間)進(jìn)行對(duì)比,。
 
badloops.php
 
<?php
require_once(‘Benchmark/Iterate.php‘);
define(‘MAX_RUN‘,100);
$data = array(1, 2, 3, 4, 5);

doBenchmark(‘v1‘, $data);
doBenchmark(‘v2‘, $data);
doBenchmark(‘v3‘, $data);
function
doBenchmark($functionName = null, $arr = null)
{
    
reset($arr);
    
$benchmark = new Benchmark_Iterate;
    
$benchmark->run(MAX_RUN, $functionName, $arr);
    
$result = $benchmark->get();
    echo
‘<br>‘;
    
printf("%s ran %d times where average exec time %.5f ms",$functionName,$result[‘iterations‘],$result[‘mean‘] * 1000);
}

function
v1($myArray = null) {
    
// 效率很差的循環(huán)
    
for ($i =0; $i < sizeof($myArray); $i++)
    {
        echo
‘<!--‘ . $myArray[$i] . ‘ --> ‘;
    }
}

function
v2($myArray = null) {
    
// 效率略有提高
    
$max = sizeof($myArray);
    for (
$i =0; $i < $max ; $i++)
    {
        echo
‘<!--‘ . $myArray[$i] . ‘ --> ‘;
    }
}

function
v3($myArray = null){
    
//最佳效率
    
echo "<!--", implode(" --> <!--", $myArray), " --> ";
}
?>
 
  程序輸出的結(jié)果大概是這樣的:
 
v1 ran 100 times where average exec time 0.18400 ms
v2 ran 100 times where average exec time 0.15500 ms
v3 ran 100 times where average exec time 0.09100 ms
 
  可以看到,函數(shù)的執(zhí)行時(shí)間變少,,效率上升,。
  函數(shù)v1有個(gè)很明顯的錯(cuò)誤,每一次循環(huán)的時(shí)間,,都需要調(diào)用sizeof()函數(shù)來(lái)計(jì)算,。函數(shù)v2則在循環(huán)外把$myArray數(shù)組的元素個(gè)數(shù)存到$max變量中,避免了每次循環(huán)都要計(jì)算數(shù)組的元素個(gè)數(shù),,所以效率提高了,。函數(shù)v3的效率最高,利用了現(xiàn)成的函數(shù),,避免循環(huán),。
  這個(gè)例子只是給你一個(gè)感性的認(rèn)識(shí),明白什么是相對(duì)高效的代碼,。在實(shí)際開(kāi)發(fā)中,,我相信會(huì)有很多人會(huì)迷迷糊糊地寫(xiě)出很多低效率的代碼。要把代碼寫(xiě)得精煉而高效,,恐怕需要時(shí)間去錘煉:-) 但這是另一個(gè)話題了,,我們略過(guò)不談。
  數(shù)據(jù)庫(kù)應(yīng)用基本上每個(gè)PHP程序都會(huì)用到,,在實(shí)際開(kāi)發(fā)中我發(fā)現(xiàn)最影響整個(gè)系統(tǒng)效率的就是數(shù)據(jù)庫(kù)這部份,。至于數(shù)據(jù)庫(kù)的優(yōu)化和數(shù)據(jù)查詢語(yǔ)句的優(yōu)化,在此限于篇幅不詳細(xì)討論,。你可以參看這兩篇文章:
  及這篇討論:
http://club./index.php?s=&act=ST&f=15&t=4783&st=0(前面幾篇貼子總結(jié)不錯(cuò)),,主要是針對(duì)MySQL的。
 
壓縮輸出 gzip
 
  利用Apache中的mod_gzip模塊,,我們可以利用gzip的壓縮算法來(lái)對(duì)Apache服務(wù)器發(fā)布的網(wǎng)頁(yè)內(nèi)容進(jìn)行壓縮后再傳輸?shù)娇蛻舳说臑g覽器,。如果是純文本的內(nèi)容,效果非常明顯,,大約可以壓縮到原來(lái)的30%-40%,,使用戶的瀏覽速度大大加快,。
  Gzip需要客戶端瀏覽器支持,目前大部份瀏覽器都支持gzip,,如IE,,Netscape,Mozilla等,所以這種方法值得一試,。我們可以利用PHP中的預(yù)定義變量$_SERVER[‘HTTP_ACCEPT_ENCODING’]來(lái)判斷客戶端瀏覽器是否支持gzip,。
 
gzip1.php

<?php
if(ereg(‘gzip‘,$_SERVER[‘HTTP_ACCEPT_ENCODING‘])) {
    
//瀏覽器支持
} else {
    
//瀏覽器不支持,輸出其它內(nèi)容
}
?>
 
  接下來(lái)我們對(duì)上面這個(gè)PHP程序進(jìn)行擴(kuò)展,,使用ob_start(ob_gzhandler)來(lái)將網(wǎng)頁(yè)內(nèi)容壓縮,,存入緩沖并發(fā)送給支持gzip的瀏覽器,瀏覽器會(huì)自動(dòng)將壓縮后的內(nèi)容解壓,,顯示,。
 
gzip2.php
 
<?php
define
(‘MAX‘,100);

if(
ereg(‘gzip‘,$_SERVER[‘HTTP_ACCEPT_ENCODING‘]))
{
    
//瀏覽器支持gzip,將內(nèi)容壓縮并緩沖輸出
    
ob_start("ob_gzhandler");
    
$output = ‘‘;

    for(
$i=0;$i<=MAX;$i++)
    {
        
$output .= "This is line $i
"
;
    }
    echo
"瀏覽器支持gzip壓縮輸出
"
;
    echo
$output;
}
else
{
    
//瀏覽器不支持,,直接輸出
    
for($i=0;$i<=MAX;$i++)
    {
        
$output .= "This is line $i
"
;
    }

    echo
"瀏覽器不支持gzip壓縮輸出
"
;
    echo
$output;
}
?>

 
  使用gzip壓縮生成的網(wǎng)頁(yè)的HTTP頭信息與一般的網(wǎng)頁(yè)相比中會(huì)多出這樣的信息:
 
Content-Encoding: gzip
Content-Length: 270
 
  如果你想得到更詳細(xì)的信息,,請(qǐng)參看mod_gzip項(xiàng)目主頁(yè):
 
  類似地,我們也可以利用mod_deflate,,壓縮率比mod_gzip略低一些。調(diào)用zip函數(shù)需要耗用服務(wù)器內(nèi)存,,所以要慎用,,視需求而定。
 
內(nèi)容緩存輸出 PEAR cache
 
  接下來(lái)我們開(kāi)始探索更常用的緩存技術(shù),,這也是本文的重點(diǎn)部份,。首先我們使用PEAR中的cache包。PEAR可以將內(nèi)容緩存于文件,,數(shù)據(jù)庫(kù)或者內(nèi)存中,,我們以文件為例。
  下面是一個(gè)沒(méi)有使用緩存的PHP小程序:
 
pear_content_cache1.php
 
<?php
echo "這是內(nèi)容,。<P>"
;
echo
"當(dāng)前時(shí)間是" . date(‘M-d-Y H:i:s A‘, time()) . "<BR>"
;
?>
 
  上面這個(gè)程序非常簡(jiǎn)單,,現(xiàn)在我們?yōu)槠浼由暇彺妗?/div>
 
pear_content_cache2.php
 
<?php
require_once ‘Cache/Output.php‘
;

//設(shè)置緩存目錄,必須是可寫(xiě)的
$cacheDir = ‘./pear_cache‘
;
$cache = new Cache_Output(‘file‘,array(‘cache_dir‘ => $cacheDir
));

//如果nocache變量為空,,使用緩存中的內(nèi)容
//如果想獲得最新的內(nèi)容,,就要賦值給nocache變量
if (empty($_REQUEST[‘nocache‘
]))
{
    
// 建立一個(gè)獨(dú)一的cache標(biāo)識(shí)
    // 請(qǐng)求+Cookie信息
    
$cache_id = $cache->generateID(array(‘url‘ => $_REQUEST,‘post‘ =>$_POST,‘cookies‘ => $HTTP_COOKIE_VARS
));
}
else
{
    
//想獲得最新的內(nèi)容,ID為空
    
$cache_id = null
;
}


//看cache ID對(duì)應(yīng)的緩存內(nèi)容是否可用
if ($content = $cache->start($cache_id
))
{
    
//緩存已存在,,直接輸出,,并結(jié)束腳本
    
echo $content
;
    exit();
}

// 緩存中不存在該內(nèi)容,生成新內(nèi)容并寫(xiě)入緩存
echo "這是內(nèi)容,。<P>"
;
echo
"當(dāng)前時(shí)間是" . date(‘M-d-Y H:i:s A‘, time()) . "<BR>"
;
// 把內(nèi)容寫(xiě)入緩存
echo $cache->end
();
?>
 
  分別刷新這兩個(gè)文件,,你會(huì)發(fā)現(xiàn)pear_content_cache1.php中的“當(dāng)前時(shí)間是”這一行中的時(shí)間是隨著刷新而變化的,,而pear_content_cache2.php中的這一行則不變。這是由于pear_content_cache2.php使用了緩存,,將用戶請(qǐng)求的內(nèi)容存入靜態(tài)文件中,。當(dāng)用戶再次請(qǐng)求時(shí),它直接從文件中輸出,,而不需要用程序動(dòng)態(tài)生成內(nèi)容,。
  對(duì)于pear_content_cache2.php,如果用戶想要讀取最新的信息,,而不是緩存中成舊的信息,。那么可以用http://…/pear_content_cache2.php?nocache=1 來(lái)訪問(wèn),這將禁用緩存功能,。刷新一下看看,,你將發(fā)現(xiàn)時(shí)間會(huì)隨之變化。
  總結(jié)一下PEAR內(nèi)容緩存類的使用:
  1.包含PEAR包 要注意設(shè)對(duì)路徑,。
  2.包含Output.php中的cache類
require_once ‘Cache/Output.php‘;
  3.設(shè)置緩存目錄
$cacheDir = ‘./pear_cache‘;
  確認(rèn)這個(gè)目錄是可寫(xiě)的,。Cache數(shù)據(jù)將會(huì)寫(xiě)入這個(gè)目錄的子目錄中。
  4.建立一個(gè)輸出緩存對(duì)象
$cache = new Cache_Output(‘file‘,array(‘cache_dir‘ => $cacheDir));
  第一個(gè)參數(shù)表示我們使用基于“文件”方式的緩存,,第二個(gè)參數(shù)是一個(gè)與緩存目錄相關(guān)聯(lián)的數(shù)組,。
  5.產(chǎn)生一個(gè)唯一的cache ID
$cache_id = $cache->generateID(array(‘url‘ => $_REQUEST,‘post‘ =>$_POST,‘cookies‘ => $HTTP_COOKIE_VARS));
  這里$cache對(duì)象的generateID()方法通過(guò)提供一個(gè)信息數(shù)組(URL, HTTP POST data, 和 HTTP cookie)來(lái)獨(dú)一無(wú)二地標(biāo)識(shí)這個(gè)請(qǐng)求,與其它請(qǐng)求區(qū)分開(kāi)來(lái),。
  6.增加一個(gè)邏輯判斷語(yǔ)句看是否對(duì)應(yīng)于cacheID的緩存數(shù)據(jù)是否已經(jīng)存在,,如果存在,獲取數(shù)據(jù)并結(jié)束腳本,。
if ($content = $cache->start($cache_id))
{   echo $content;
    exit();
}
  7. 將產(chǎn)生內(nèi)容的代碼放在以上邏輯語(yǔ)句之后,,并結(jié)束使用cache對(duì)象。
echo $cache->end();
 

函數(shù)緩存輸出 PEAR cache

  PEAR除了可以對(duì)輸出的內(nèi)容進(jìn)行緩存處理外,,還可以將對(duì)某個(gè)函數(shù)的調(diào)用結(jié)果緩存起來(lái),。這是個(gè)很有趣的功能,如果你的程序要頻繁使用到某個(gè)函數(shù),,而且調(diào)用的結(jié)果相同的話,,我建議你不妨試試,特別是當(dāng)這個(gè)函數(shù)運(yùn)行起來(lái)比較慢的時(shí)候,。

  下面我們實(shí)現(xiàn)對(duì)一個(gè)執(zhí)行起來(lái)很慢的函數(shù)slowFunction()的緩沖調(diào)用,。
 
<?php
require_once ‘Cache/Function.php‘
;


$cacheDir = ‘./pear_cache/‘
;
$cache = new Cache_Function(‘file‘,array(‘cache_dir‘ => $cacheDir
));
$arr = array(‘蘋(píng)果‘, ‘梨‘,‘西瓜‘
);
$cache->call(‘slowFunction‘, $arr
);
echo
‘<BR>‘
;

$arr = array(‘蘋(píng)果‘, ‘梨‘,‘西瓜‘
);
slowFunction($arr
);

function
slowFunction($arr = null
)
{
    echo
"一個(gè)執(zhí)行起來(lái)很慢的函數(shù) :( <br>"
;
    echo
"當(dāng)前時(shí)間是 " . date(‘M-d-Y H:i:s A‘, time()) . ‘<br>‘
;
    foreach (
$arr as $fruit
)
    {
        echo
"我吃了一個(gè) $fruit <br>"
;
    }
}
?>
 
       以下是示例的腳本執(zhí)行結(jié)果:
一個(gè)執(zhí)行起來(lái)很慢的函數(shù) :(
當(dāng)前時(shí)間是 Jul-28-2004 17:15:57 PM
我吃了一個(gè) 蘋(píng)果
我吃了一個(gè) 梨
我吃了一個(gè) 西瓜

一個(gè)執(zhí)行起來(lái)很慢的函數(shù) :(
當(dāng)前時(shí)間是 Jul-28-2004 17:17:55 PM
我吃了一個(gè) 蘋(píng)果
我吃了一個(gè) 梨
我吃了一個(gè) 西瓜
  代碼中,Cache/Function.php類用來(lái)執(zhí)行函數(shù)緩沖功能,。$cache變量是一個(gè)Cache_Function對(duì)象,,使用基于文件的函數(shù)緩存,存入$cacheDir目錄。要緩存一個(gè)函數(shù)調(diào),,Cache_Function對(duì)象$cache的call()方法要像這樣使用:$cache->call(‘slowFunction’, $arr);
  這里,,slowFunction()函數(shù)被調(diào)用,參數(shù)為一個(gè)數(shù)組$arr,,這個(gè)函數(shù)被緩存在$cacheDir目錄下的一個(gè)文件里,。任何在此之后的對(duì)這個(gè)函數(shù)的調(diào)用,將會(huì)由$cache->call()返回該函數(shù)執(zhí)行的結(jié)果,。
  函數(shù)緩存和使用方法和內(nèi)容緩存很相似,,不再多說(shuō),具體請(qǐng)查看PEAR手冊(cè),。
 
  以上我們都是利用優(yōu)化代碼的方法對(duì)程序進(jìn)行提速,,接著我們要關(guān)注一下PHP加速的另一個(gè)領(lǐng)域—緩存工具軟件。這類軟件都是從優(yōu)化PHP運(yùn)行環(huán)境來(lái)提速的,,不需要改變?nèi)魏未a,。我們可以大概地將它們稱為“執(zhí)行碼優(yōu)化/緩存工具”,你可以理解為它們用來(lái)實(shí)現(xiàn)比較底層的優(yōu)化/緩存,。
 
  以下列出目前比較常用的此類工具,,具體哪種效果最好,請(qǐng)用自己的服務(wù)器環(huán)境測(cè)試:
(一)APC Alternative PHP Cache
  APC運(yùn)行于Linux和FreeBSD,,你需要自己編譯安裝,。按照其開(kāi)發(fā)人員的說(shuō)法,在他們的測(cè)試環(huán)境下可以提高腳本速度50%-400%,。并且APC是個(gè)開(kāi)源項(xiàng)目,,已經(jīng)加入了PHP的PECL庫(kù),很值得一試,。
(二)Turck MMCache
http://turck-mmcache./
  Turck MMCache似乎是此類軟件中目前最受歡迎的一種,它開(kāi)放源代碼,,完全免費(fèi),。它將PHP代碼預(yù)編譯并緩存起來(lái),同時(shí)也對(duì)PHP運(yùn)行環(huán)境進(jìn)行一定優(yōu)化,。按照其官方文檔的說(shuō)法,,MMCache可以明顯地減輕服務(wù)器的負(fù)載,并提高腳本執(zhí)行速度1-10倍,。
  MMCache與另一個(gè)知名的加速軟件Zend Optimizer兼容,,但注意必需先安裝MMCache(php.ini中設(shè)置)。除了加快PHP程序的速度,,MMCache還可以將PHP代碼加密,。
  Turck MMCache同時(shí)支持Linux和Win32平臺(tái)。
(三)PHPA  the PHP Accelerator
  PHPA又是另一個(gè)流行的PHP加速軟件,。在其官方網(wǎng)站上有分別使用PHPA與APC,、Zend Cache的PHP腳本執(zhí)行測(cè)試對(duì)比,,其表現(xiàn)略優(yōu)于APC,略遜于Zend Cache,。
    PHPA支持Linux, FreeBSD, OpenBSD, BSDi和Solaris系統(tǒng).
(四)Zend Performance Suite
    Zend Performance Suite是老牌的PHP加速/優(yōu)化軟件,,依托于PHP領(lǐng)域最知名的Zend公司。目前已經(jīng)推出4.0版本,,它可以為PHP應(yīng)用提供程序加速,,內(nèi)容緩存,文件壓縮,,下載服務(wù)等,,功能十分強(qiáng)大,獲得好幾個(gè)PHP雜志的推薦獎(jiǎng)—但是不得不提起,,它也很昂貴,,目前的價(jià)格是1875美元。
以上幾種加速軟件,,希望讀者按照服務(wù)器環(huán)境自行測(cè)試并選擇其中最適用的,,因?yàn)槲覜](méi)有辦法提供一個(gè)普遍適用的測(cè)試標(biāo)準(zhǔn)來(lái)判斷哪種方案是最有效的。綜合起來(lái)看,,我個(gè)人認(rèn)為T(mén)urck MMCache是個(gè)值得推薦的選擇,,免費(fèi)而且功能相當(dāng)出色。
 
(四)總結(jié)
 
   以上從多個(gè)角度較為全面細(xì)致地闡述了PHP加速的相關(guān)技術(shù),,包括測(cè)試技術(shù),,加速技術(shù)(壓縮,緩存等),,基本上都有附代碼和范例,。希望本文有助于讀者全面了解PHP程序加速并在實(shí)際應(yīng)用中選擇合適的加速方案。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多