画像などの静的コンテンツのファイルに直接アクセスした場合は
ブラウザが自動的にキャッシュ制御を行ってくれますが、
PHPで静的コンテンツを返すような処理を行っている場合にキャッシュを利用するには
Last-Modifiedヘッダを使ってキャッシュを制御する必要があります。
まず、PHPでファイルをダウンロードさせる際に
filemtime関数でファイルの更新日時を取得してLast-Modifiedヘッダを追加します。
1 |
header('Last-Modified: filemtime('ファイルのパス')); |
さらにキャッシュを残すためのヘッダも追加します。
1 2 |
header('Pragma: cache'); header("Cache-Control: max-age=" . (60 * 60 * 24 * 30)); // 有効期間30日の例 |
そうすると、次に同じファイルをダウンロードしようとした際のリクエストヘッダの中に
1 |
HTTP_IF_MODIFIED_SINCE |
というヘッダが追加され、ファイルの更新日時が入っています。
ですので、このヘッダの有無を調べ、ファイルの更新日時と比較することで
ファイルを返すかキャッシュを返すかを判定します。
1 2 3 4 5 6 7 8 9 10 11 |
$filelastmodified = filemtime('ファイルのパス'); if(isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])){ $headerlastmodified = $_SERVER["HTTP_IF_MODIFIED_SINCE"]; if(strtotime($headerlastmodified == strtotime($filelastmodified)){ // 更新日が一致したのでキャッシュを返す // (正しくはレスポンスコード304を返す) } else { // ファイルを返す } } |
レスポンスコード304を返す処理は下記の通りです。
1 2 3 |
header("HTTP/1.1 304 image not modified"); header('Pragma: cache'); header("Cache-Control: max-age=" . (60 * 60 * 24 * 30)); |
ちなみに、Etagというヘッダを使ってキャッシュを制御することもできますが
Etagはどちらかというと動的コンテンツのキャッシュで利用するためのものです。
静的コンテンツのキャッシュにもEtagを使ったサンプルが多くみられるのですが
Last-Modifiedヘッダだけで十分だと思います。