2008-09-04 9 views

ответ

9

Apache использует стандартный формат inode-filesize-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

Почему не `header (sprintf ('Etag:"% x-% x-% 016x "', $ fs ['ino'], $ fs ['size'], $ fs ['mtime'])) ; `? – 2011-06-11 09:35:18

+1

Я заметил, что часть MTime в ETag моего сервера Apache на самом деле имеет очень точное значение MTime, оно также использует микросекунды. Поэтому, если вы хотите генерировать ETag точно так же, как это делает Apache, вам понадобится microtime времени mtime. Насколько мне известно, это невозможно в PHP. Однако вы можете проверить, достаточно ли для Apache MTime_close_ (<1 с), чтобы вы могли хотя бы вернуть `304 Not Modified`. – Halcyon 2012-02-06 13:20:07

1

Если вы динамически генерируете свою страницу, это, вероятно, не имеет смысла. Если вы находитесь на PHP, вы можете выбрать индекс и размер файла основного сценария, но время изменения не скажет вам, изменились ли ваши данные. Если у вас нет хорошего процесса кеширования или просто создается статические страницы, этиги не помогают. Если у вас есть хороший процесс кэширования, размер inode и размер файла, вероятно, не имеет значения.

Редактировать: Для людей, которые не знают, что такое etag - они должны быть значением, которое изменяется при изменении содержимого для целей кеширования. Браузер получает etag с веб-сервера, сравнивает его с etag для своей кешированной копии, а затем извлекает всю страницу, если этаг изменился.

+0

Этот подход может быть полезен для таких вещей, как сценарии загрузки, которые просто передают файлы через PHP и другие ситуации, когда ответы не являются фактически динамическими по запросу. – 2012-09-16 23:10:14

2

Одна вещь, которую следует помнить об Etags от Apache, заключается в том, что они не хорошо работают в кластерах, потому что они включают информацию об иноде, которая может и, возможно, будет варьироваться между машинами в одном кластере.

+3

Добавьте `FileETag MTime Size` в ваш .htaccess, чтобы сделать inode inode независимым. – Halcyon 2012-02-11 00:54:40

1

ответ выше (от Chris) работает хорошо, но можно упростить, используя неявное приведение в Sprintf:

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

%016x Предложенном не работает, потому что обивка применяется после преобразования в шестнадцатеричном , а не раньше.