14

私の質問はかなりカジュアルに見えると思いますが、面白くなるので我慢してください(少なくとも私にとっては:))。

ファイルシステムから要求されたファイルを読み取り、それを応答としてエコーすることを目的とする PHP ページを考えてみましょう。問題は、このページのキャッシュを有効にする方法です。指摘すべきことは、ファイルがかなり巨大になる可能性があり、キャッシュを有効にすると、クライアントが同じコンテンツを何度もダウンロードするのを防ぐことができるということです.

理想的な戦略は、リバース プロキシ キャッシュ システムを実装するために、「If-None-Match」リクエスト ヘッダーと「ETag」レスポンス ヘッダーを使用することです。私はここまで知っていても、これが可能かどうか、またはこの手法を実装するために応答として何を返す必要があるかはわかりません!

4

1 に答える 1

25

PHP で巨大な、または多くの補助ファイルを提供することは、まさにその目的のために作成されたものではありません。

代わりに、nginx のX-accel、Lighttpdの X-Sendfile 、Apache のmod_xsendfileを見てください。

最初のリクエストは 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、コンテンツがその間に変更されたかどうかを判断するために使用できます。

于 2012-05-15T07:40:08.060 に答える