Я хочу сделать etag, который соответствует тому, что производит Apache. Как apache создает его etags?
Как вы делаете etag, который соответствует Apache?
Ответ 1
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)));
Ответ 2
Одна вещь, которую следует помнить об Apache Etags, заключается в том, что они не очень хорошо играют в кластерах, потому что они включают информацию об иноде, которая может и, возможно, будет варьироваться между машинами в одном кластере.
Ответ 3
Если вы динамически генерируете свою страницу, это, вероятно, не имеет смысла. Если вы находитесь на PHP, вы можете выбрать индекс и размер файла основного script, но время изменения не сообщит вам, изменились ли ваши данные. Если у вас нет хорошего процесса кеширования или просто создается статические страницы, этиги не помогают. Если у вас есть хороший процесс кеширования, размер inode и файла, вероятно, не имеет значения.
Изменить: для людей, которые не знают, что etag - они просто должны быть значением, которое изменяется, когда содержимое было изменено для целей кэширования. Браузер получает etag с веб-сервера, сравнивает его с etag для его кешированной копии, а затем извлекает всю страницу, если этаг изменился.
Ответ 4
ответ выше (от Криса) работает хорошо, но может быть упрощен с использованием неявного литья в sprintf:
sprintf('"%x-%x-%x"', $s['ino'], $s['size'], str_pad($s['mtime'], 16, "0"));
Предлагаемый %016x
не работает, потому что добавление применяется после преобразования в hex, а не раньше.