2012-05-15 15 views
14

創建我覺得我的問題似乎很隨意,但忍耐一下,因爲它(至少對我來說:))變得有趣。緩存HTTP響應時,他們通過動態PHP

考慮一個PHP頁面,其目的是爲了讀取文件系統上的請求的文件和回聲它作爲響應。現在的問題是如何爲這個頁面啓用緩存?需要指出的是,這些文件可能非常大,並且啓用緩存功能可以讓客戶端一次又一次地下載相同的內容。

理想的策略是使用「如果 - 無 - 匹配」請求頭和「ETag的」響應報頭中,爲了實現反向代理高速緩存系統。儘管我知道這一點,但我不確定這是否可行,或者我應該如何回覆以實施此技術!

+0

酷眼。儘管如此,仍然不匹配我的。 –

+0

不要這麼確定,眼睛的主人現在是Juubi的Jinchuuriki! – Mehran

+0

現在,但我的王牌還沒有透露。讓我們繼續聊聊[動漫與漫畫聊天](http://chat.stackexchange.com/rooms/6697/anime-and-manga)。不要混亂這個線程。 –

回答

25

服務巨大或者有很多輔助文件用PHP不正是它的製作。

相反,看X-accel爲nginx的,X-Sendfile對Lighttpd的或mod_xsendfile爲Apache。

最初的請求被PHP處理,但是一旦下載文件被確定,它就會設置一些頭文件來指示服務器應該處理文件發送,之後PHP進程被釋放以供其他用途。

然後,您可以使用Web服務器來配置緩存爲您服務。

靜態生成的內容

如果從PHP生成的內容,特別是昂貴的創建,你可以寫輸出到一個本地文件,並再次應用上述方法。

如果您不能寫入到本地文件或不想,你可以使用HTTP響應頭控制緩存:

Expires: <absolute date in the future> 
Cache-Control: public, max-age=<relative time in seconds since request> 

這將導致客戶端緩存的頁面內容,直到它過期或者當用戶強制頁面重新加載時(例如按F5)。

動態生成的內容

爲您希望瀏覽器每次執行ping你的動態內容,但只有當有新發的頁面內容。

ETag: <hash of the contents> 
Last-Modified: <absolute date of last contents change> 

當瀏覽器再次ping您的腳本,它們將分別增加了以下請求標頭:您可以通過設置一些其他的響應頭做到這一點

If-None-Match: <hash of the contents that you sent last time> 
If-Modified-Since: <absolute date of last contents change> 

ETag主要是用來減少網絡流量在某些情況下,要知道內容散列,您首先必須計算它。

Last-Modified是最簡單的,如果你有本地緩存​​文件(文件有一個修改日期)申請。一個簡單的條件下也可以正常工作:

if (!file_exists('cache.txt') || 
    filemtime('cache.txt') > strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { 
    // update cache file and send back contents as usual (+ cache headers) 
} else { 
    header('HTTP/1.0 304 Not modified'); 
} 

如果你不能做文件緩存,你仍然可以使用ETag來確定內容是否同時變化。

+0

這是我的錯,我忘了提及,消除PHP是不可能的。在PHP中可能有一個複雜的邏輯。 – Mehran

+0

@MehranZiadloo也許你沒有得到我的答案,我已經改寫過它。 –

+0

即使您的更新闡明瞭您的觀點,但恐怕仍然無法消除PHP,因爲內容有時會生成而不是加載。不管怎麼說,還是要謝謝你。 – Mehran