1 Feb 2001 prenagha   » (Apprentice)

Worked out a server-side caching mechanism for PHP based sites. This is extremely helpful to performance. Somewhat like the concept of a reverse-cache sitting in front of a webserver, like squid, but this can be used on those hosts that don't have that software installed. Here is a snapshot of the PHP code, usage should be self-explanatory. I just started testing it, but so far so good.

function pageCacheStart($ttl=600, $debug=FALSE, 
  $cacheDir='/tmp/pagecache', $sidName='psid') {
  global $HTTP_SERVER_VARS, $HTTP_GET_VARS,
$HTTP_COOKIE_VARS;

//to force the cache OFF, uncomment next line //return FALSE;

// we only use the cache for GET requests. // we don't use the cache for ssl requests. if ($HTTP_SERVER_VARS['REQUEST_METHOD']!='GET' || isset($HTTP_SERVER_VARS['HTTPS']) ) { return FALSE; }

$REQUEST_URI = $HTTP_SERVER_VARS['REQUEST_URI'];

// if we have the sid in the get vars, // and we have the sid in the cookie vars, // then we can act as if the sid is not in the get // vars and return a cached page. // if the sid is in the get, and not as a cookie, // then we don't use a cached version since all the URLs // in the page need to be rewritten with the sid by php. if (isset($HTTP_GET_VARS[$sidName])) { if (isset($HTTP_COOKIE_VARS[$sidName])) { if (count($HTTP_GET_VARS)==1) { $REQUEST_URI = $HTTP_SERVER_VARS['SCRIPT_NAME']; } else { $REQUEST_URI = ereg_replace('&'.$sidName.'=.{32}','',$REQUEST_URI); } } else { return FALSE; } }

// get the hostname if (isset($HTTP_SERVER_VARS['HTTP_HOST'])) { $HOST = $HTTP_SERVER_VARS['HTTP_HOST']; } else { $HOST = $HTTP_SERVER_VARS['SERVER_NAME']; }

// cache directory use for pages from this host. $cacheDirHost = $cacheDir.'/'.strtolower($HOST);

// build the name of the cache file for this page $cacheFile = $cacheDirHost.'/'.md5($REQUEST_URI).'.cache';

$mtime = filemtime($cacheFile); $time = time();

if ($mtime >= ($time - $ttl)) {

//send cache control headers that let client browser //cache the page. header('Expires: '.gmdate('D, d M Y H:i:s', $time + $ttl).' GMT'); header('Last-Modified: '.gmdate('D, d M Y H:i:s', $mtime).' GMT'); header('Cache-Control: public'); header('Cache-Control: max-age='.$ttl);

//get the cached file and send it to the browser immediately readfile($cacheFile);

//debug info if ($debug) { print("<hr>CACHED COPY
filename: $cacheFile\n"); print("
mtime: ".date('m/d/y h:i:s a',filemtime($cacheFile))."\n"); print("
cache age ".(time()-filemtime($cacheFile))." seconds\n"); }

//exit this server session exit();

} else { // the directory existence is the signal that pages // from this host should be cached. if (!is_dir($cacheDirHost)) { return FALSE; }

ob_start(); print("<!-- request: ".$HOST.$REQUEST_URI." -->\n"); return $cacheFile; } }

function pageCacheEnd($cacheFile='', $debug=FALSE) { $html = ob_get_contents(); ob_end_flush();

if (empty($cacheFile)) { } else { if ($debug) { print("<hr>writing new cacheFile: $cacheFile\n"); }

if ($fp = @fopen ($cacheFile, 'w')) { @fwrite ($fp, $html); @fclose ($fp); } } }

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!