Как сделать etag, который соответствует Apache?


Я хочу сделать etag, который соответствует тому, что производит Apache. Как apache создает it's etags?

4 12

4 ответа:

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)));

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

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

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

Ответ выше (от Криса) работает хорошо, но может быть упрощен с помощью неявного приведения в sprintf:

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

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