2008-09-04 7 views

答えて

9

Apacheは、iノード・ファイルサイズ・ファイルのmtimeの標準フォーマットを使用しています。これに対する唯一の注意点は、mtimeはエポックタイムでなければならず、ゼロが埋め込まれているため16桁であることです。 PHPでそれを行う方法は次のとおりです:

$fs = stat($file); 
header("Etag: ".sprintf('"%x-%x-%s"', $fs['ino'], $fs['size'],base_convert(str_pad($fs['mtime'],16,"0"),10,16))); 
+1

なぜ 'ヘッダ(のsprintf( 'のEtag: "%X-%X-%の016x"'、$ FS [ 'イノ']、$ FS [ 'サイズ']、$ FS [ 'のmtime'])) ; '? –

+1

私は、ApacheサーバのETagのMTime部分が実際には多くのプリシーザMTimeを持っていることに気がつきました。それはマイクロ秒も使用しています。ですから、Apacheが正確にETagを生成したいのであれば、mtimeの微小時間が必要になります。私の知る限り、これはPHPでは不可能です。しかし、あなたができることは、ApacheのMTimeが_close enough_(<1秒)であるかどうかをチェックすることです。したがって、少なくとも「304 Not Modified」を返すことができます。 – Halcyon

1

あなたのページを動的に生成しているのであれば、これはおそらく意味がありません。 PHPを使用している場合は、メインスクリプトのinodeとファイルサイズを選択できますが、データが変更されたかどうかは変更時にはわかりません。良いキャッシングプロセスや静的ページを生成しない限り、etagsは役に立ちません。良いキャッシングプロセスがある場合、iノードとファイルサイズはおそらく無関係です。

編集:etagが何であるかわからない人のために、コンテンツが変更されたときに変更される値であると考えられています。ブラウザはWebサーバーからetagを取得し、キャッシュされたコピーのetagと比較し、etagが変更された場合はページ全体を取得します。 ApacheのEtagsとについて覚えておくべき

+0

このアプローチは、PHPを介してストリームファイルをダウンロードするスクリプトや、レスポンスが実際にリクエストごとに動的でないその他の状況に役立ちます。 –

2

の一つは、彼らができる - と、おそらく同じクラスタ内のマシンの間で、変化しますiノード情報が含まれているため、彼らはクラスタ内にうまく再生されないということです。

+3

'FileETag MTime Size'を.htaccessに追加して、Etag inodeを独立させます。 – Halcyon

+0

Apacheバージョン2.4では、デフォルトでINodeが含まれなくなりました。 – holmis83

1

(クリスから)上記の答えはうまく動作しますが、sprintfの中で暗黙のキャストを使用して単純化することができます。

sprintf('"%x-%x-%x"', $s['ino'], $s['size'], str_pad($s['mtime'], 16, "0")); 

パディングが進に変換した後に適用されるため、ザ・が%016xが動作しない提案、以前よりもむしろ。

+0

これは**動作しません**、理由は分かりません。なぜなら%xは 'int'を入力として必要とするからでしょうか? – Halcyon

+1

@FritsvanCampen:それはそれより少し複雑です。 'sprintf'は文字列を' int'にキャストしようとしますが、これらの数値は大きすぎるのでオーバーフローして問題を引き起こします。溶液を代わりfloat' '使用することである:'はsprintf( ' "%X-%X-%X"'、$ S [ 'イノ']、$ S [ 'サイズ']、(フロート)str_pad($ S [ 'mtime']、16、 '0')) '。 –