Мой файл CSS на самом деле является файлом PHP, который обслуживается с типом содержимого text/css, так что я могу использовать переменные PHP в этом файле. style.php выглядит так:

<?php
header('Content-Type: text/css');
$bgColor = '#000';
?>

body { background:<?php print $bgColor; ?>; }

Он работает так, как ожидалось, но меня немного беспокоит, кэширует ли браузер динамически созданный файл css.

При просмотре запросов в firebug мне кажется, что браузер загружает style.php заново каждый раз, когда я перезагружаю страницу.

Я уже пробовал добавить эти заголовки кеша:

header('Cache-control: must-revalidate');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 60 * 60 * 24) . ' GMT');

Но не повезло. Файл по-прежнему загружается каждый раз при загрузке страницы. Каковы подходящие заголовки, чтобы браузер кэшировал файл на определенное время?

8
Max 7 Мар 2010 в 11:16

2 ответа

Лучший ответ

Если вы хотите, чтобы файл кэшировался браузерами, вы должны установить для заголовка Cache-control значение public:

header('Cache-control: public');

Must-revalidate означает, что браузер проверит, был ли файл обновлен, что вызовет ваш скрипт PHP.

2
Inspire 7 Мар 2010 в 11:25
5
Согласно спецификации HTTP / 1.1, это не то, что должно означать must-validate - оно должно срабатывать только после того, как кэшированный контент стал устаревшим (как указано в заголовке Expires или в значении max-age в Cache-Control. ), но некоторые браузеры, похоже, игнорируют спецификацию и все равно отправляют запрос. Однако «общедоступный» на самом деле неприменим, если соединение не аутентифицировано. Я бы использовал Cache-Control: max-age = 86400, чтобы усилить время в заголовке Expires.
 – 
Brock Batsell
7 Мар 2010 в 11:41
Batsell: спасибо за комментарий! Это прояснило это, и теперь он работает с max-age = XXXX.
 – 
Max
7 Мар 2010 в 12:11
Если содержимое файла изменится, запрошенный файл не будет обновлен. OP требует, чтобы файл не кэшировался при изменении содержимого. Если содержимое файла не изменилось, его следует кэшировать. Предоставленный вами код включает функцию «кэширования». Это не решает проблему OP.
 – 
Wissam El-Kik
9 Дек 2014 в 17:30
Приведенный выше ответ необходимо обновить, чтобы отразить комментарии и решение.
 – 
Basil Musa
15 Июн 2015 в 15:53

Этот код решает вашу проблему.

Он проверяет переменную "последнего изменения" и присваивает файлу eTag. Если eTag изменен (или файл изменен), файл отображается. В противном случае возникает ошибка HTTP 304, в которой говорится, что страница не была изменена.

На самом деле eTag - это то, что вы ищете.

Код:

<?php 
// Custom variables
$variables = array('#CCC','#800'); // from db

// CSS Content
header('Content-type: text/css');

// Last Modified
$lastModified = filemtime(__FILE__);

// Get a unique hash of this file (etag)
$etagFile = md5_file(__FILE__);

// Get the HTTP_IF_MODIFIED_SINCE header if set
$ifModifiedSince = (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false);

// Get the HTTP_IF_NONE_MATCH header if set (etag: unique file hash)
$etagHeader = (isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : false);

// Set last-modified header
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $lastModified)." GMT");

// Set etag-header
header("Etag: $etagFile");

// Make sure caching is turned on
header('Cache-Control: public');

// Check if page has changed. If not, send 304 and exit
if(@strtotime($ifModifiedSince) == $lastModified || $etagHeader == $etagFile){
   header("HTTP/1.1 304 Not Modified");
   exit;
}
?>
body {background: <?php echo $variables[0]; ?>;}
2
Wissam El-Kik 9 Дек 2014 в 17:25