jurchiks
jurchiks

Reputation: 1403

php headers for serving css via php

Here's the thing. I'm serving somewhat compressed CSS content

(`str_replace(array("\r", "\n", "\t", '\s\s+'), '', cssGoesHere)`) 

via a PHP file in my page:

<link rel="stylesheet" type="text/css" href="/css/loader.css.php" />

The question is: how do I make the browser cache the css returned, BUT update the cache if the content is changed?

The PHP file is not being modified, so appending something like

<?php echo filemtime('/css/loader.css.php'); ?>

to the href attribute is not an option. Can this be solved with headers, and if so, how? Because AFAIK if I serve it like I wrote above, the browser will just cache the result and keep reusing the cache (provided, of course, the browser is enabled/capable of doing so), but I need it to know when the content is changed.

Edit: I've made a github project with my code (though I did change it alot for more flexibility since I wrote this). Here's the link: https://github.com/jurchiks/YACC
If you have any suggestions, write them to my e-mail or smth.

Upvotes: 1

Views: 189

Answers (5)

mohammad falahat
mohammad falahat

Reputation: 748

use this in your css php page:

header('Content-type: text/css');
header("Cache-Control: no-cache, must-revalidate");

you can see more information about headers in PHP's official documentation

Upvotes: 1

Jen
Jen

Reputation: 584

You could add a version number to the CSS link href and use mod rewrite to route it back to the original CSS file.

For example. Let's say you start with version 1 (note the version appendix to the file name):

<link rel="stylesheet" type="text/css" href="/css/loader-v001.css.php" />

The browser will cache this file. The next time you update the CSS file and you don't want the browser to use the cache file, simply change the version number like this:

<link rel="stylesheet" type="text/css" href="/css/loader-v002.css.php" />

Then, in your mod rewrite, route any request for the file loader-v{x}.css.php to loader.css.php.

I am not sure if this is 'automated' enough for your needs, as it does require manual changing of the version number. However, the different file name will ensure the browser sees it as an actual 'new' file and re-downloads it.

Upvotes: 1

Gntem
Gntem

Reputation: 7155

i would suggest to keep somewhere the time that the cache content was generated for example style.php which holds the CSS data was last modified at 21/06/2012 and cache content was last generated at 20/06/2012 running a comparison on dates in strtotime() integers, you see that the cached content must be generated again from the new content.

Upvotes: 0

Death
Death

Reputation: 2017

The only way to reliably make the file load upon change is the method you state. Otherwise, the page will cache the file and keep it for as long as it thinks necessary. It can't check to see whether the page has changed or not without requesting and downloading at least the headers, and if it's gone that far it might as well just download the rest of the page, as the bandwidth will be minimal.

The best alternative if you really can't append the modified date to the HTML, would be to set the cache headers via PHP.

header("Cache-Control: max-age=time-in-seconds");

This doesn't always work though, as server settings and browser settings can override this, especially in aggressive caching browsers such as Internet Explorer.

Upvotes: 1

user1474553
user1474553

Reputation:

It can be solved by headers cache-control, BUT this have proved to be not very effective. Because some browser do overwrite or modify your forced settings.

I can't see where you getting the CSS data from, if it's a CSS file you could get the filemtime of the css file as version indicator or simply supply somewhere a version string which has to be changed each time the CSS file changes.

By the way, str_replace(array("\r", "\n", "\t", '\s\s+'), does not effectively remove all newlines. Your should use something like

$foo = nl2br($string, FALSE);
$bar = str_replace(array('<br>', '\s\s+'), '', cssGoesHere)

instead.

HTH :)

Upvotes: 1

Related Questions