SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
てるてる動画

【php】file_get_contents()で If-Modified-Sinceヘッダを送って 304 Not Modified をもらう

問題

file_get_contents()関数でファイルを取得するのですが、一度取得したらファイルを保存しておいて、ブラウザでアクセスするときみたいに、変更がなかったら 304 Not Modified を受け取って、保存済みのファイルを使うようにしたいです。

答え

雰囲気はこんな感じ

$data = '';
if (is_file('/tmp/cache') && is_file('/tmp/cache.info')) {
	$info = json_decode(file_get_contents('/tmp/cache.info'));
	$last_modified = '';
	foreach ($info as $v) {
		if (strpos($v, 'Last-Modified:') === 0) {
			$last_modified = substr($v, 15);
			break;
		}
	}
	if ($last_modified) {
		$options = array(
			'http' => array(
				'header' => array(
					'If-Modified-Since: ' . $last_modified
				)
			)
		);
		file_get_contents('https://example.com/sample.xml', false, stream_context_create($options));
		if ($http_response_header[0] == 'HTTP/1.1 304 Not Modified') {
			$data = file_get_contents('/tmp/cache');
		}
	}
}
if (! $data) {
	$data = file_get_contents('https://example.com/sample.xml');
	file_put_contents('/tmp/cache', $data);
	file_put_contents('/tmp/cache.info', json_encode($http_response_header));
}

一度アクセスしたら、キャッシュ(/tmp/cache)と、レスポンスヘッダ(/tmp/cache.info)を作っておく。(cacheというファイル名は重複する可能性があるので状況に応じて考える)

キャッシュ(/tmp/cache)と、レスポンスヘッダ(/tmp/cache.info)があれば、前回のレスポンスの「Last-Modified」を取得して、今回のリクエストヘッダの「If-Modified-Since」に使う。

サーバーのファイルが更新されていなかったら 304 Not Modified が返ってくる。

304 が返ってきたらキャッシュ(/tmp/cache)を使い、304でなかったら改めてファイルを取得する。

関連するメモ

コメント