PHP cache to ensure visitors always get new content

I want to set the correct header / cache values for a site.

I am working on a social network / forum style site.

I want to ensure that every page a user requests results in a fresh one being requested from the server as most content changes by the minute.

(1) How would I set this?

(2) Also, can I prevent nav bars being reloaded as these never, ever change.

I am pretty sure php handles this by default by sending some cache control headers that prevent caching.
but you can add these lines to you php code to force sending these headers
Headers must be send before any other content is sent or you will get the error.

header( ‘Expires: Sat, 26 Jul 1997 05:00:00 GMT’ );
header( ‘Last-Modified: ’ . gmdate( ‘D, d M Y H:i:s’ ) . ’ GMT’ );
header( ‘Cache-Control: no-store, no-cache, must-revalidate’ );
header( ‘Cache-Control: post-check=0, pre-check=0’, false );
header( ‘Pragma: no-cache’ );

I don’t know what you mean by prevent nav bar being reloaded. I don’t know what the nav bar is.

Imagine a forum where there are 2 parts:

(1) The content that changes regularly based on user input.
(2) the main navigartion bar that was designed once and rarely changed.

I want the content to always be reloaded EVERY time, but browsers can cache the navigation bar if they want as no need for my seperate nav bar files to be reloaded every time.

Is this possible?

Then you need to update only part of the html page, which some people refer to as Ajax. Or you can use frames and have your navigation bar in top frame and the forum main content in another frame under it.

As a normal whole page you can’t cache different parts separately because it’s all one document. There are workarounds that lampcms just posted, but I wouldn’t bother. The Ajax method would need a fall back (i.e having that content in your page anyway…so no markup saving) and frames aren’t ideal either.

If you compress your pages there won’t be a problem.

Yes, but not with any PHP framework currently in existence that I know of.

Then you may want to take a look at Symfony 2.0. :slight_smile:

Read over it, and not impressed. I’m working out a system that should be quite a bit faster. I may end up being wrong, but I don’t think so. In any case I find YAML to be a major turn off - why waste processor time with that library when the native parse_ini_file() is going to be a hell of a lot faster. I could see the point in using YAML prior to PHP 5.3, but with the additions to ini formats as of 5.3 there’s really no excuse for the thing.

I also dislike this common practice of frameworks wanting you to learn their own special syntaxes for paths and routes rather than using PHP’s natural extensibility.

I’m only going to set headers in PHP, I won’t use other methods.

If I set the headers to expire in 5 minutes, would that do the job (so user has 5 minutes where navigation bars / graphics not reloaded but will get content updated soon enough).

Maybe I should set pages either to:
(i) expire days / weeks if home page / nav bar
(ii) expire 5 mins for most
(iii) no cache for forums and other v.important things

How does Sitepoint do it?

Cache headers only affect the whole page, not sections of pages. Piecemeal caching of pages is involved as I’m discovering as I work it out for myself.

Thanks, but I don’t think this answers my question (or does it?).

This does.

Maybe I should have started another post. My latest questions are slightly different. I have accepted that I can’t cache diffrent parts of the page seperately.

If I set the headers to expire in 5 minutes, would that allow the user to surf for 5 minutes where navigation bars / graphics are not reloaded. Then, after 5 minutes, new content will be loaded from the db.

Maybe I should set pages either to:
(i) expire days / weeks if home page / nav bar
(ii) expire 5 mins for most others (peoples’ profiles)
(iii) no cache for forums and other v.important things

You can have different cache times for the images, javascript, css files and other assets of the page than the dynamic content uses. Indeed since this stuff rarely changes once the site goes to deployment most sites set these to have no expiry on their cache.

Your server is probably already doing this - PHP doesn’t normally serve asset files unless mod_rewrite is in play (and if its done right it shouldn’t do it even then).

I’d recommend switching to Firefox and picking up the plug in “Web Developer”. This will add a toolbar to the browser and one of the tools is an information menu. In that menu you can view the headers for the document. To see the headers that accompanied an image open the image in it’s own tab. You’ll find the image gets it’s own set of headers independent from the html page’s headers, and it’s cache settings can (usually should) be different.

You can set your cache headers to expire in 5 minutes if you wish. This would mean that browser will not attempt to re-download your php page if it already has a cached version and it’s been downloaded less than 5 minutes ago. This means that if a new post has been added to your forum a minute after you first visit the forum page, then you go to another page, then click a link back to your forum page, you will not see that new post.
This is why by default php sends no-cache headers. It’s very difficult process to cache dynamic pages in browser. Consider the situation when you log in to a site. You first visit the forum and presented with a login form. You enter your name/password and login. But you browser may decide to still show you the cached version of the page because it’s not older than 5 minutes, which means you will see the page with the login form again, even though you are already logged in.

Consider another situation of multi-lingual site where you visit it originally see default language, you then select your prefferend language from the drop-down menu but when you reload the page you see the same page, nothing’s changed! This is because the page was cached by browser, so it does not re-download the new page with you newly selected language preference.

In short, caching dynamically generated pages in browser is difficult. That’s why by default php sends on all the necessary no-cache headers.

There are 2 distinctly different types of cache headers. One of them basically tells the browser to NOT check the server for a new version if cached version exists in browser cache.

Another type tells the browser to still check with the server to see if a new version exists on the server.

This is really an advanced topic, not really specific to php. I recommend not to worry about this at first, just make your scripts, make it work, then worry about browser caching or not caching, research this topic and decide which and how to do this. This can be done in web server configuration or in php itself. stick with defaults for now.

Michael Morris, Thanks for the reply. I’ll look into this.

I imagine if you cached all images there is still a way for the user to see updates, is there? Imagine if you did this, but needed to change just one image file - what would it take for the user to get that new file (other than hoping they one day clear their browser cache)., thanks for the reply.

I was thinking more of setting so that login forms and forums are not cached, user profile pages are set to expire 5 minutes later and the home page to be cached for 24 hours.

Would this work, or is it more hassle than it’s worth?

This will not work if you have login forms on all pages. If you don’t have login form on user profile page, then it may work. This is advanced topic, don’t worry about it too much at first.