Cache Control using htaccess file

When a user visits a webpage, which contains an image, the browser will first check if it has the image in it’s cache. If it does, it will ask your web server if it has a newer version. If there isn’t a newer version, then the browser doesn’t download the image again, and instead displays it using its cached version. That’s very nice, because you do not have to send the image to the user again, but the web server has had to do a little work by checking the last time the file was updated. You can stop the browser asking so frequently by using a cache control header. This basically tells the browser not to ask if there is an updated version until a certain amount of time has passed. One way of setting this cache control up is using a .htaccess file. This assumes that you are using Apache.

The following example tells the browser to cache any gif, jpg, or png files for 1 month:

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/gif "access plus 1 months"
ExpiresByType image/png "access plus 1 months"
ExpiresByType image/jpg "access plus 1 months"

You could extend that to cache any CSS or javascript files by adding the following:

<IfModule mod_expires.c>
ExpiresByType text/javascript "modification plus 1 months"
ExpiresByType application/javascript "modification plus 1 months"
ExpiresByType text/css "modification plus 1 months"

Alternatively, you could use the following, which caches anything with the listed extension for 1 day

<FilesMatch "\.(ico|pdf|jpg|jpeg|png|gif|js)$">
Header set Cache-Control "max-age=86400"

I personally use the final example, because it’s easier to list the file extensions, rather than listing the mimetypes.

How many seconds in an hour/day/week?

When setting a DNS Time To Live, or a cache control header, I often have to get a calculator to work out how many seconds there are in an hour, day or week. Here are some common examples to refer to.

60 seconds in 1 minute.
3600 seconds in 1 hour.
86400 seconds in 1 day.
604800 seconds in 1 week.
2592000 seconds in 1 month. In this example 1 month = 30 days.
31536000 seconds in 1 year. In this example 1 year = 365 days.

Cache control in PHP

Set a cache control expiry for a PHP page. This will mean a repeat visitor will only request a new copy of the page if their cached version is older than the date/time specified in the Expires setting.

//sets an expiry of plus one hour
header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + 3600)); 
header('Cache-Control: public');
header('Pragma: cache');

Ensure that you do this before sending any content to the browser.

You can use this cache cheatsheet to determine how many seconds you want to enter in the code above.

I would only recommend using cache control for php pages that are either very large, or that require a lot of computing power to generate. Also, only use this if you do not plan on updating the page within the expiry timeframe. There is no easy way for you to force a user to retrieve a fresh copy from your site. You could ask them to refresh their cache by hitting F5, but that’s not ideal.

You could also use your web server (Apache, or nginx) to determine the cache control, but I dont tend to use cache control for php files, and instead use it for static files, like css, javascript or images.