Reputation: 8509
I'm having problems with serving CSS files from PHP. For test I'm just loading content from existing CSS file into PHP variable and than echo it. I want to set headers to allow caching of file until it was modified.
PHP code
$css_file_path = "path-to-existing-css-file";
$file_content = file_get_contents ($css_file_path);
$fmtime = date ("r", filemtime ($css_file_path));
header ("Content-type: text/css");
header ("X-Content-Type-Options: nosniff");
header ("Last-Modified: " . $fmtime);
die ($file_contents);
This is done by simple PHP code as shown above. For some reason it's never cached (tested in latest Firefox only).
I have tried to put this line before die() function to test it.
echo date ("r", time());
And it gets updated all the time. I'm such a caching noob, I admit it, so all I want to do is to make file being cached until new modification arrives.
So far, I have read tones of different posts here and web-wide and mostly found nothing or very poor information on this subject.
What am I missing and is it possible to achieve at all?
Upvotes: 1
Views: 1526
Reputation: 11836
To start with
I want to do is to make file being cached until new modification arrives
The only way a browser can know there is a new modification, is by asking the server whether their cached version is still valid.
This is done as followed:
1. Browser requests /style.css
GET /style.css
2. Server sends to browser
HTTP/1.1 200 OK
Last-Modified: Wed 2 Aug 2017 21:28:00 GMT
Cache-Control: must-revalidate, max-age=31536000
... file-contents ...
// 31536000 is about 1 year
3. Next time browser wants that file it sends
GET /style.css
If-Modified-Since: Wed 2 Aug 2017 21:28:00 GMT
4a. Your server can read that header, and verify if the file isn't modified after
the given date. If it isn't, you can reply with a single:
HTTP/1.1 304 Not Modified
... without sending the contents again
4b. If your file was hower modified after Aug 2, you should sent a response simalar
as in step 2
So in code, step 2, add the Cache-Control-header:
header('Cache-Control: must-revalidate, max-age=31536000');
And step 4a, act to the If-Modified-Since request-header:
$css_file_path = "path-to-existing-css-file";
$fmtimestamp = filemtime ($css_file_path);
// Check header set by browser
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $fmtimestamp <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
die(); // We're done here
}
// Otherwise continue as ussualy
$file_content = file_get_contents ($css_file_path);
Alternative solution, without using the If-Modified-Since
, but it depends on the situation if this is usable for you:
// Somewhere in your HTML
<link rel="stylesheet" href="/style.css?version=<?php echo filemtime($pathToStyle.css) ?>" />
When your file changes, the link changes and the browser would see it as a new file. In that case you can leave the must-revalidate
-part out of the Cache-Control
-header and the browser won't reload the style.css
unless the max-age expires or cache is cleaned up.
Upvotes: 4