首頁  >  文章  >  後端開發  >  php快取並壓縮動態頁面的技巧詳解

php快取並壓縮動態頁面的技巧詳解

伊谢尔伦
伊谢尔伦原創
2017-06-24 13:40:181117瀏覽

mod_gzip是一個Apache模組,其功能是使用Gzip壓縮靜態的html頁面,遵循IETF標準的瀏覽器可以接受gzip編碼(IE, Netscape等)。 mod_gzip可以將頁面的下載時間提高4-5倍。我強烈建議你在你的網頁伺服器上使用mod_gzip。然而,我們也必須用PHP建立自己的壓縮引擎。在這篇文章裡,我將要介紹如何使用PHP的輸出控制函數來大幅加速頁面載入速度。

介紹PHP的輸出控制函數

PHP4中最令人滿意的事是-你可以讓PHP快取所有由腳本產生的輸出,在你決定把它們送出之前,瀏覽器方是不會收到任何內容的。在腳本程式中你能用這些函數來設定header、cookies,然而這只是強大的輸出函數的一小部分功能。

<?php 
void ob_start(void); 
?>

告訴PHP處理器把所有的輸出重定向到一個內部的快取(buffer)中。在呼叫ob_start之前,沒有輸出會被送到瀏覽器去。

<?php 
string ob_get_contents(void); 
?>

此函數將「輸出快取」(output buffer)以字串的形式傳回。你可以呼叫該函數把累積下來的輸出送到瀏覽器中。 (僅在把buffering功能關閉之後!!)

<?php 
int ob_get_length(void); 
?>

返回快取中的字串的長度。

<?php 
void ob_end_clean(void); 
?>

清空輸出快取,並將輸出快取關閉。在快取中的內容輸出到瀏覽器之前,必須先使用這個函數。
void 501([int flag])
用來開啟/關閉隱含的flush動作開關(預設是關)。如果flush是開的,每次呼叫print/echo或是其它輸出指令的時候,輸出的內容會立即被送到瀏覽器端。

使用輸出控制來壓縮PHP輸出
你必須使用PHP4裡編譯的Zlib擴充包來壓縮輸出。如果需要的話,可以查看PHP文件中有關Zlib包的安裝指導。
首先,初始化輸出快取:

<?php 
ob_start(); 
ob_implicit_flush(0); 
?>

之後,用print, echo, 或其他你喜歡的方法產生所有輸出內容,例如:

<?php
print("Hey this is a compressed output!"); 
?>

頁面產生後,我們取回輸出內容:

<?php 
$contents = ob_get_contents(); 
ob_end_clean(); 
?>

之後,必須偵測瀏覽器是否支援壓縮資料。如果支援,瀏覽器會發給伺服器端一個ACCEPT-ENCODEING HTTP頭。我們只需檢查$HTTP_ACCEPT_ENCODING變數中是否有「gzip,deflate」字串。

<?php 
if(ereg(&#39;gzip, deflate&#39;,$HTTP_ACCEPT_ENCODING)) { 
// 在这里生成 Gzip 压缩的内容 
} else { 
echo $contents; 
} 
?>

這種方法使用起來既簡單又結構清晰。下面讓我們來看看如何產生壓縮的輸出:

<?php 
//告诉浏览器将要收到的是gzip数据 
//当然在此之前,你已经检查了它们是否支持gzip,x-gzip数据格式 
//如果支持的是x-gzip,那么下面的头就要用z-gzip来代替 
header("Content-Encoding: gzip");
//显示gzip文件的头 
//只需显示一次 
echo "x1fx8bx08x00x00x00x00x00";
//计算出文件的大小和CRC码 
$Size = strlen($contents); 
$Crc = crc32($contents);
//压缩数据 
$contents = gzcompress($contents, 9);
//我们不能就这样输出,因为CRC码是混乱的。 
//如果我在这里使用“echo $contents”,压缩的数据会被送出, 
//但是却不完整。文件最后的四个字节是CRC校验码,可是只发出去了三个字节。 
//最后一个字节被丢掉了。我不知道这个bug在4.0.2版中解决了没有, 
//不过最好避免错误的方法是把正确的CRC校验码加到压缩的数据的末尾。 
// 
//把旧的CRC校验码剥离 
$contents = substr($contents, 0, strlen($contents) - 4);
//仅显示压缩的数据 
echo $contents;
//输出CRC,和原来数据的大小(字节) 
gzip_PrintFourChars($Crc); 
gzip_PrintFourChars($Size);
function gzip_PrintFourChars($Val) { 
for ($i = 0; $i <4; $i ++) { 
echo chr($Val % 256); 
$Val = floor($Val / 256); 
} 
}
?> 
//好了,你还可以按此方式附加上更多的压缩数据。

要想進行實際的測試,所有的腳本程式碼如下:

<?php 
ob_start(); 
ob_implicit_flush(0);
print("I&#39;m compressed!n");
$contents = ob_get_contents(); 
ob_end_clean();
header("Content-Encoding: gzip");
echo "x1fx8bx08x00x00x00x00x00";
$Size = strlen($contents); 
$Crc = crc32($contents);
$contents = gzcompress($contents, 9);
$contents = substr($contents, 0, strlen($contents) - 4);
echo $contents;
gzip_PrintFourChars($Crc); 
gzip_PrintFourChars($Size);
function gzip_PrintFourChars($Val) { 
for ($i = 0; $i <4; $i ++) { 
echo chr($Val % 256); 
$Val = floor($Val / 256); 
} 
} 
?>

快取PHP輸出

當PHP4還沒問世,我必須使用PHP3的時候,我對開發一些快取機制來減少資料庫的載入、對檔案系統的存取十分感興趣。在PHP3中沒有什麼特別好的方法,但是有了輸出快取之後,在PHP4中一切變得容易多了。
這有一個簡單的例子:

<?php 
//为请求的URI构造一个文件名 
$cached_file=md5($REQUEST_URI);

if((!file_exists("/cache/$cached_file"))||(!is_valid("/cache/$cached_file"))) { 
//is_valid函数验证缓存,你可以用这个函数检查Cache是否过期或其他特定的条件。 
//如果文件不在Cache中或者不可用则生成输出 
ob_start(); 
ob_implicit_flush(0); 
//在此输出……
$contents = ob_get_contents(); 
ob_end_clean(); 
$fil=fopen($cached_file,"w+"); 
fwrite($fil,$contents,$strlen($contents)); 
fclose($fil); 
}
/如果请求的文件在缓存中且可用,则: 
readfile($cached_file);
?>

這是一個簡單的例子,使用輸出緩存,你可以建立一個複雜的內容生成系統,對不同的區塊或程式使用不同的快取機制,等等…

結論

PHP輸出控制函數對把腳本產生的輸出重新導向到快取中十分有用。為支援gzip的瀏覽器輸出壓過的快取資料可以減少載入時間。也可作為快取機制來減少對資料來源的存取(資料庫或檔案),這對使用XML意義重大。
如果我們用PHP建立一個引擎,快取從資料來源得到的資料(xml文件和資料庫),並且動態的產生XML格式的內容(沒有外觀-presentation)我們可以得到這些XML的輸出,並使用XSLT轉換成任何一種我們想要的外觀格式(html, wap, palm, pdf等)。使用PHP4的輸出快取和Sablotron XSLT擴充可以很好地完成這個任務。

以上是php快取並壓縮動態頁面的技巧詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn