Я думаю, что мой вопрос кажется довольно случайным, но неся со мной, поскольку он становится интересным (по крайней мере для меня :)).
Рассмотрим страницу PHP, целью которой является чтение запрошенного файла из файловой системы и повторение его в качестве ответа. Теперь вопрос в том, как включить кеш для этой страницы? Дело в том, что файлы могут быть довольно огромными и позволять кешу сохранять клиенту от загрузки одного и того же контента снова и снова.
Идеальной стратегией будет использование заголовка запроса If-None-Match и заголовка ответа ETag для реализации системы обратного прокси-кэша. Несмотря на то, что я знаю это далеко, я не уверен, что это возможно или что я должен вернуть в качестве ответа, чтобы реализовать эту технику!
Обслуживание огромных или многих вспомогательных файлов с PHP не совсем то, для чего оно сделано.
Вместо этого посмотрите на X-accel для nginx, X-Sendfile для Lighttpd или mod_xsendfile для Apache.
Первоначальный запрос обрабатывается PHP, но как только файл загрузки был определен, он устанавливает несколько заголовков, чтобы указать, что сервер должен обрабатывать отправку файла, после чего процесс PHP освобождается, чтобы обслуживать что-то еще.
Затем вы можете использовать веб-сервер для настройки кэширования для вас.
Статический контент
Если ваш контент генерируется из PHP и особенно дорог для создания, вы можете записать вывод в локальный файл и снова применить вышеуказанный метод.
Если вы не можете писать в локальный файл или не хотите, вы можете использовать заголовки ответов HTTP для управления кешированием:
Expires: <absolute date in the future> Cache-Control: public, max-age=<relative time in seconds since request>
Это приведет к тому, что клиенты будут кэшировать содержимое страницы до истечения срока ее действия или когда пользователь заставляет перезагружать страницу (например, нажмите F5).
Динамически сгенерированный контент
Для динамического содержимого вы хотите, чтобы браузер каждый раз пингал вас, но только отправляйте содержимое страницы, если есть что-то новое. Вы можете выполнить это, установив несколько других заголовков ответов:
ETag: <hash of the contents> Last-Modified: <absolute date of last contents change>
Когда браузер снова запустит ваш скрипт, они добавят следующие заголовки запросов соответственно:
If-None-Match: <hash of the contents that you sent last time> If-Modified-Since: <absolute date of last contents change>
ETag
в основном используется для снижения сетевого трафика, как и в некоторых случаях, чтобы знать хэш содержимого, вам сначала нужно его вычислить.
Last-Modified
является самым простым в применении, если у вас есть локальные кеши для файлов (файлы имеют дату модификации). Простое условие заставляет его работать:
if (!file_exists('cache.txt') || filemtime('cache.txt') > strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { // update cache file and send back contents as usual (+ cache headers) } else { header('HTTP/1.0 304 Not modified'); }
Если вы не можете делать файловые кеши, вы все равно можете использовать ETag
чтобы определить, изменилось ли содержимое в то же время.