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

分享

如何分離個(gè)人信息,,緩存動(dòng)態(tài)頁面

 zybingliu 2008-04-30

肖理達(dá) (KrazyNio AT hotmail.com), 2005.06.07, 轉(zhuǎn)載請(qǐng)注明出處

一直想寫一篇關(guān)于動(dòng)態(tài)頁面 cache 的文章,但每次“提筆”卻又放棄,,因?yàn)榭偸怯X得準(zhǔn)備得還不夠充分,。今天埋頭寫下,只是希望對(duì)自己的工作做一些筆錄,。

1,、問題起源

我們經(jīng)常會(huì)在一個(gè)動(dòng)態(tài)頁面中加入很多個(gè)人信息,以 CMS 首頁為例,,用戶登錄之前顯示登錄框,,登錄之后顯示其用戶名,并根據(jù)權(quán)限顯示其可用模塊的鏈接,。由于每個(gè)用戶登錄之后,,顯示出來的動(dòng)態(tài)信息都是不一樣的,,所以這部分無法進(jìn)行 cache,我們將這部分信息定義為“[u]個(gè)人信息[/u]”,,它的特性是根據(jù)登錄用戶進(jìn)行動(dòng)態(tài)改變,。

現(xiàn)在問題來了,就是一個(gè) CMS 的首頁,,訪問者的登錄概率并不是百分百的,,應(yīng)該說有一大部分人訪問首頁是沒有登錄的,這個(gè)時(shí)候的首頁是一個(gè)公共的頁面,,沒有任何個(gè)人信息,,或者說這時(shí)候首頁的任何動(dòng)態(tài)信息都是可以轉(zhuǎn)換成靜態(tài)的,也就是說這部分是可 cache 的,。

2,、使用 JavaScript 分離個(gè)人信息

解決這個(gè)問題的方法有很多種,一種是將個(gè)人信息和其他信息進(jìn)行分離,,如在 CMS 首頁中加入一個(gè)外部的 JavaScript 文件,,而這個(gè)文件的內(nèi)容實(shí)際上是由 PHP 動(dòng)態(tài)生成的。CMS 首頁 index.php 代碼片段:

<script language="JavaScript" src="/js/personal.php"></script>
            ….
            <script language="JavaScript">
            document.write(sUser);
            document.write(sLinks);
            </script>
            

personal.php 代碼片段:

<?php
            session_start();
            header("Cache-Control: no-store, no-cache, must-revalidate");
            ?>
            sUser = "<?php echo $_SESSION['USER']; ?>";
            sLinks = "<?php echo addslashes($_SESSION['LINKS']); ?>";

這種方法比較適合個(gè)人信息較少,,易于集中顯示的情況,。通過 JavaScript 外掛代碼實(shí)現(xiàn)個(gè)人信息分離之后,personal.php 是永不 cache 的,,這樣也就可以放心地對(duì) CMS 首頁進(jìn)行 cache 了,,具體的 cache 方法可采用 304 HTTP 頭與 Cache_Lite 相結(jié)合的方式,這在后邊有詳細(xì)代碼示例,。

3,、選擇性分離個(gè)人信息

一旦個(gè)人信息較多,很難對(duì)其進(jìn)行分離的時(shí)候,,上述方法實(shí)現(xiàn)起來就會(huì)比較麻煩了,。接下來介紹一種比較放寬的 cache 方式,就是只對(duì)用戶未登錄的 CMS 首頁進(jìn)行 cache,,一旦發(fā)現(xiàn)用戶處于登錄狀態(tài),,則跳過 cache 部分,直接運(yùn)行相關(guān)代碼,,我把這種方法稱為“[u]選擇性 cache[/u]”,。這種方法中,我們犧牲了一部分可 cache 的情況,,但很大程度上提高了個(gè)人信息的可擴(kuò)充性,,也就是說個(gè)人信息的多少、顯示的位置等等都不再受到限制,,這是值得的,,畢竟修改服務(wù)端代碼要比修改大量的 JavaScript 代碼要來得方便,,而且 JavaScript 的調(diào)試也會(huì)比較麻煩。

分析一下這種 cache 方式,,概要流程圖如下:

 

 

 

代碼片段如下:

<?php
            session_cache_limiter("must-revalidate");
            session_start();
            if (empty($_SESSION['USER'])) { //未登錄時(shí)才使用 cache
                 ….     //輸出 cache
            } else {
                 //   直接輸出頁面內(nèi)容,,此條件下與未使用 cache 時(shí)一樣
                 $data =& get_data();
                 echo $data;
            }    //end if
            ?>

這里需要說明的一點(diǎn)是,由于 PHP 在使用 SESSION 時(shí),,php.ini 中默認(rèn)設(shè)置的 session.cache_limiter 為 nocache,,所以需要修改 cache_limiter,設(shè)置成 must-revalidate,,使得客戶端再次瀏覽當(dāng)前頁時(shí)必須發(fā)送相關(guān) HTTP 頭信息到服務(wù)器進(jìn)行驗(yàn)證,然后才決定是否加載客戶端本地 cache,。不要把客戶端本地 cache 與服務(wù)器端 cache 搞混,,之后的代碼片段中會(huì)充分利用客戶端 cache 和 服務(wù)器端 cache 機(jī)制達(dá)到緩存的目的。關(guān)于 must-revalidate,,請(qǐng)參考 HTTP 規(guī)格說明書 RFC 2612 的 14.9.4 章節(jié),。

上邊的代碼并不完整,接下來是更加深入的探討客戶端 cache 機(jī)制了,,利用客戶端 cache,,可以有效地減輕服務(wù)器端負(fù)載。首先了解一下 HTTP 頭:Last-Modified 與 If-Modified-Since,。簡單的說,,Last-Modified 與If-Modified-Since 都是用于記錄頁面最后修改時(shí)間的 HTTP 頭信息,只是 Last-Modified 是由服務(wù)器往客戶端發(fā)送的 HTTP 頭,,而 If-Modified-Since 則是由客戶端往服務(wù)器發(fā)送的頭,,其工作原理圖如下:

 

 


可以看到,再次請(qǐng)求本地存在的 cache 頁面時(shí),,客戶端會(huì)通過 If-Modified-Since 頭將先前服務(wù)器端發(fā)過來的 Last-Modified 最后修改時(shí)間戳發(fā)送回去,,這是為了讓服務(wù)器端進(jìn)行驗(yàn)證,通過這個(gè)時(shí)間戳判斷客戶端的頁面是否是最新的,,如果不是最新的,,則返回新的內(nèi)容,如果是最新的,,則返回 304 告訴客戶端其本地 cache 的頁面是最新的,,于是客戶端就可以直接從本地加載頁面了,這樣在網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)就會(huì)大大減少,,同時(shí)也減輕了服務(wù)器的負(fù)擔(dān),。想要詳細(xì)查看 HTTP 頭信息,可以在 Firefox 中安裝 LiveHTTPHeaders 插件,,安裝完成之后按 Alt+L 就可以在 Sidebar 中看到了,。

現(xiàn)在再來完善之前的 index.php 代碼:

<?php
            session_cache_limiter("must-revalidate");
            session_start();
            function &get_data()
            {
                 //此函數(shù)用于獲取本頁面的輸出內(nèi)容
                 //….
            }    //end function
            if (empty($_SESSION['USER'])) { //未登錄時(shí)才使用 cache
                 //====================================================
                 //   1. 檢查 HTTP 頭是否符合 304 的條件
                 //====================================================
                 //get_last_modified() 函數(shù)需要另外單獨(dú)實(shí)現(xiàn),,此函數(shù)用于獲取服務(wù)器端 cache 文件的最后修改時(shí)間,可將時(shí)間戳保存在數(shù)據(jù)庫中,。
                 $last_modified = get_last_modified();
                 $headers = getallheaders();
                 if (strtotime($headers['If-Modified-Since']) == $last_modified) {
                     //   返回 304 并結(jié)束程序運(yùn)行
                     header('HTTP/1.1 304 Not Modified');
                     exit;
                 }    //end if
                 header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $last_modified) . ' GMT');
                 //====================================================
                 //   2. 檢查 cache 文件是否存在
                 //====================================================  
                 require_once 'Cache/Lite.php';
                 //   參數(shù)設(shè)置
                 $options = array(
                     'cacheDir' => './cache/',
                     'lifeTime' => 86400, //最大 cache 一天時(shí)間
                     'fileNameProtection'    => false //使用 CMS 自身提供的 id 作為名字
                 );
                 $cache = new Cache_Lite($options);   //創(chuàng)建 Cache_Lite 對(duì)象
                 $id = md5($_SERVER['REQUEST_URI']); //生成對(duì)應(yīng)于 cache 文件的 ID
                 if ($data = $cache->get($id)) {    //存在 cache 文件,,獲取內(nèi)容,直接輸出
                     echo $data;
                 } else {
                     $data =& get_data();
                     echo $data;
                     flush();
                     $cache->save($data);     //保存 cache
                 }    //end if
            } else {
                 $data =& get_data();
                 echo $data;
            }    //end if
            ?> 

測試時(shí)可以使用 LivHTTPHeaders 插件,,你將會(huì)看到第一次訪問時(shí)是返回 200,,第二次到第N次訪問時(shí)則返回了 304,而登錄之后,,則一直都返回 200,,因?yàn)槲覀冞x擇性 cache 之后,對(duì)登錄之后一律運(yùn)行程序輸出,,而不使用 cache,,如果之后需要對(duì)輸出的個(gè)人信息進(jìn)行修改,只需要改函數(shù) get_data() 即可,,也避免了 JavaScript 的調(diào)試,。

總結(jié)

除此之外,還有其它方法可以實(shí)現(xiàn)分離個(gè)人信息,,緩存動(dòng)態(tài)頁面的目的,。而且為了提高服務(wù)器運(yùn)行效率,還可以使用數(shù)據(jù)庫 cache,、Squid 反向代理等,,如 ADOdb 的 cache。目前用的比較多的 Drupal 應(yīng)用的就是本文中提到的第二種方法,。

參考資料

HTTP Caching & Cache-Busting for Content Publishers
Hypertext Transfer Protocol — HTTP/1.1
PHP Anthology, Volume 2: Applications. Chapter 5: Caching
Caching Tutorial for Web Authors and Webmasters
Drupal 源代碼

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(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)論公約

    類似文章 更多