This website stores cookies. Click here to accept them.cookie information page

"caching" category

all about caching

31st December 2011
Categories: caching, php, programming

Caching is when the web server, the browser, or even an intermediate server store a copy of an image, javascript file, css file, or html page, in order to prevent the browser from putting too big a load on the web server by requesting the same page multiple times - for example if you're browsing around a site and frequently return to the home page, or if all of the pages use the same css stylesheet.

So that's a good thing, right?

Unfortunately caching can inconvenience the web developer quite a bit. Take for instance, a website with a little "your basket" sign in the top right corner, informing the user that the basket contains 1 item. When the user hits the home page again, they won't particulalry understand if the sign now says "nothing in your basket". Or take the developer who's designed a makeover for a website, changing the css. They don't want users who are frequent visitors to come back to the site and get a mishmash of content and styles because the css won't update automatically.

Fortunately there are ways around caching problems, and ways to give developers control over caching important elements of a page without caching everything.

Within the page HTML, if you don't want the browser to cache the page, you can add a meta-tag in the page header:

 <META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">

While the browser understands this, however, an additional HTTP header is required in order to make sure that intermediate servers understand the requirement not to cache. In PHP:

<?php

header("Cache-Control: no-cache, no-store");
header("Pragma: no-cache");

?>

In Classic ASP:

<%

Response.Expires= -1
Response.AddHeader "pragma", "no-cache"
Response.AddHeader "cache-control", "no-cache"

%>

This doesn't solve the problem of cached css. Luckily, there is a very simple solution when you've just made changes to the css:

<link rel="stylesheet" href="style.css?version=2" type="text/css">

This stylesheet reference says "style.css?version=2" instead of just "style.css".  The browser has to assume that these two files are different, although if you haven't done anything fancy with intercepting calls to css files, they are in fact exactly the same file.  Once the browser has grabbed the latest file off the server by requesting style.css?version=2 then it has that file, and won't need a new one until you change the version number in your html reference to it.

But what about the benefits of caching?

We seem to have overturned the point of caching, at least with PHP pages, so how do we make up for it? My answer is to cache specific portions of the page, i.e. the ones that don't have to be up-to-the-second, and may involve a complicated set of SQL queries to get the information out. You can turn to a commercial caching solution for this, or create a cached content table which you manage yourself. Bear in mind that this will grow and need to be tidied regularly. The code below doesn't supply the housekeeping solution.

First, write the function that gets all the content. Then, when you want to write out the content, instead of calling that function, see if a cache exists. Use some unique code for your content, and call this function:

static function GetCache($UniqueRef, $MinsToCache=3000)

{

$sql='select cachevalue,lastcached from cachetable where   uniqueref='.MySQuote($UniqueRef);

$rs=mysql_query($sql);

$aRow=mysql_fetch_assoc($rs);

if($aRow==false)

return false;

else

{

$unixcachetime=strtotime($aRow['lastcached']);

if((time()-$unixcachetime)>(60*$MinsToCache))

return false;

else

return $aRow['cachevalue'];

 }

}

 

If the function returns nothing, call the content-generator function to get the content, and before outputting, cache it - something like:

 

static function DoSomeCaching($UniqueRef, $CacheValue)

{

 

$sql='UPDATE cachetable ';

$setsql=' SET uniqueref='.MySQuote($UniqueRef);

$setsql.=',cachevalue='.MySQuote($CacheValue);

$setsql.=',lastcached='.MySQuote(date('Y-m-d H:i'));

$sql.=$setsql.' WHERE uniqueref='.MySQuote($UniqueRef);

 

mysql_query($sql);

if(mysql_affected_rows()==0)

{

$sql=' INSERT INTO cachetable '.$setsql;

mysql_query($sql);

}


}

The MySQuote() function is a mysql single quote escaping function - replace calls to this with your preferred method.

© Alberon Ltd 2018

8 Standingford House
26 Cave Street
Oxford
OX4 1BA

01865 596 144

Oxford Web is a trading name of Alberon Ltd, registered company no. 5765707 (England & Wales).