Forum Moderators: coopster

Message Too Old, No Replies

template for page caching, headers and gzip

caches the page (both xml and html), and delivers headers

         

londrum

9:44 pm on Feb 6, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



like most new starters, i've struggled with page caching and delivering headers properly. i've spent ages trying to find some cut-and-paste code that does everything i want it to do, and in the end i had to read a few books and write it myself.
i admit that this code is probably far from perfect. there are probably loads of better ways of doing it, but.... it works. and when you're starting out, that's all you want it to do.
so if you're struggling like me, then here is a page template that does all of this...

(this example assumes that your page is written in XHTML strict)
1) it will cache dynamic pages into a folder called 'temp'. (you will obviously have to create that folder yourself first. and it will need to be inside the same directory as the page that you want cached).
the good thing about this script is that it will actually cache two different pages -- one for browsers that understand the xml declaration (like firefox), and another one for browsers that dont (like IE). it will also deliver the correct headers to each browser -- xml ones, or html ones. and it will serve up a different doctype as well!
2) you can adjust the amount of time that passes before the cache is refreshed. for example. if you change $recache to 60, then everyone who visits within one minute of each other will see the same page. but after one minute it will be recached again (...maybe with different content, but that's up to you)
3) you can set the 'last-modified' and 'expires' headers to whatever you want. this example will tell the visitor that the page was written at the beginning of the day, and will expire at the end of the day.
... this is not to be confused with the $recache time above. because OUR cached page is the one that is served to each visitor (and we can change the content every minute, or whatever we set it as), but if we set the 'expires' header to say next midnight, then it will be stored in HIS browser cache until then. so he will keep on seeing the same page over and over until midnight.
4) it gzips up each page, saving you some bandwidth

and you don't even need to touch the .htaccess file either.
i know that it would probably be a lot easier to use that instead of all this, but not everyone has access to it -- i know i don't, because i've got a lousy webhost!

if anyone can improve the script, that would be great. because i'm still using it myself.

<? 
$pagename='whateverpagename'; // give each page on your site a different name
$recache=60; // this is the amount of time (in seconds) that will pass before the cached page is refreshed

if(stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml"))
{
if(file_exists('temp/'.$pagename.'x.cache')&&time()-$recache<filemtime('temp/'.$pagename.'x.cache')){
ob_start();ob_start('ob_gzhandler');@readfile('temp/'.$pagename.'x.cache');ob_end_flush();
header('Last-Modified: '.gmdate('D, d M Y').' 00:00:01 GMT'); // page was generated at midnight
header('Expires: '.gmdate('D, d M Y').' 23:59:59 GMT'); // page expires at the end of today
header('Content-Type: application/xhtml+xml; charset=UTF-8');header('Content-Length: ' . ob_get_length());
ob_end_flush();exit();}ob_start();ob_start('ob_gzhandler');
echo'<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>';
}
else {
if(file_exists('temp/'.$pagename.'.cache')&&time()-$recache<filemtime('temp/'.$pagename.'.cache')){
ob_start();ob_start('ob_gzhandler');@readfile('temp/'.$pagename.'.cache');ob_end_flush();
header('Last-Modified: '.gmdate('D, d M Y').' 00:00:01 GMT'); // page was generated at midnight
header('Expires: '.gmdate('D, d M Y').' 23:59:59 GMT'); // page expires at the end of today
header('Content-Type: text/html; charset=UTF-8');header('Content-Length: ' . ob_get_length());
ob_end_flush();exit();}ob_start();ob_start('ob_gzhandler');
echo'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/HTML4.01/strict.dtd">
<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8" />';
}
?>

<title>Your page title</title>
</head>

<body>
<p>Blah blah blah blah blah blah blah</p>
</body>
</html>

<?
if(stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml"))
{
$buffer=ob_get_contents();ob_end_flush();
header('Last-Modified: '.gmdate('D, d M Y').' 00:00:01 GMT'); // page was generated at midnight
header('Expires: '.gmdate('D, d M Y').' 23:59:59 GMT'); // page expires at the end of today
header('Content-Type: application/xhtml+xml; charset=UTF-8');header('Content-Length: ' . ob_get_length());
ob_end_flush();$fp=@fopen('temp/'.$pagename.'x.cache', 'w');@fwrite($fp, $buffer);@fclose($fp);
}
else {
$buffer=ob_get_contents();ob_end_flush();
header('Last-Modified: '.gmdate('D, d M Y').' 00:00:01 GMT'); // page was generated at midnight
header('Expires: '.gmdate('D, d M Y').' 23:59:59 GMT'); // page expires at the end of today
header('Content-Type: text/html; charset=UTF-8');header('Content-Length: ' . ob_get_length());
ob_end_flush();$fp=@fopen('temp/'.$pagename.'.cache', 'w');@fwrite($fp, $buffer);@fclose($fp);
}
?>

mcibor

8:24 am on Feb 7, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Looks good to me. You could add some templating engine, pull these php out from main page (eg. use require_once) and voile.

I use a bit different engine, but my page cannot be cached.

Regards
Michal