Say I for some reason want to serve my CSS through PHP (because of pre-processing, merging, etc). What do I need to do in my PHP to make this work well? Other than the most obvious:
header('content-type: text/css; charset=utf-8');
What about headers related to caching, modification times, etags, etc? Which ones should I use, why and how? How would I parse incoming headers and respond appropriately (304 Not Modified for example)?
Note: I know this can be tricky and that it would be a lot easier to just do what I want to do with the CSS before I deploy it as a regular CSS file. If I wanted to do it that way, I wouldn’t have asked this question. I’m curious to how to do this properly and would like to know. What I do or could do beforehand with the CSS is irrelevant; I just want to know how to serve it properly 🙂
Note 2: I really would like to know how to do this properly. I feel most of the activity on this question has turned into me defending why I would want to do this, rather than getting answers on how to do this. Would very much appreciate it if someone could answer my question rather than just suggesting things like SASS. I’m sure it’s awesome, and I might try it out sometime, but that’s not what I’m asking about now. I want to know how to serve CSS through PHP and learn how to deal with the caching and things like that properly.
A commendable effort. Caching gets way too little good will. Please enjoy my short prose attempting to help you on your way.
The summary
Sending an
ETagand aLast-Modifiedheader will enable the browser to send aIf-Modified-Sinceand aIf-None-Matchheader back to your server on subsequent requests. You may then, when applicable, respond with a304 Not ModifiedHTTP status code and an empty body, i.e.Content-Length: 0. Including aExpiresheader will help you to serve fresh content one day when the content has indeed changed.The apprentice
Sounds simple enough, but it can be a bit tricky to get just right. Luckily for us all, there is really good guidance available.
Once you get it up and running, please turn to REDbot to help you smooth out any rough corners you may have left in.
The expert
For the value of the
ETag, you will want to have something you can reproduce, but will still change whenever the content does. Otherwise you will not be able to tell whether the incoming value matches or not. A good candidate for a reproducible value which still changes when the content does, is an MD5 hash of themtimeof the file being served through the cache. In your case, it would probably be a sum for all the files being merged.For
Last-Modifiedthe logical answer is the actualmtimeof the file being served. Why neglect the obvious. Or for a group of files, as in your case, use the most recentmtimein the bunch.For
Expires, simply choose an appropriateTTL, or time-to-live, for the asset. Add this number to the asset’smtime, or the value you chose forLast-Modified, and you have your answer.You may also want to include
Cache-Controlheaders to let possible proxies on the way know how to properly serve their clients.The scholar
For a more concrete response to your question, please refer to these questions predating yours: