My custom Memcached WordPress Plugin

Something that I have found irritating about using WordPress for my blogging needs is its performance – or lack thereof! On a blog like Ideologics (that is mainly information based) rebuilding each page whenever it is viewed leads to an incredible waste of processing power.

Memcached was developed by the authors of LiveJournal, and can be used in many ways to optimise a website. My method is to simply cache an entire page’s HTML the first time it is viewed.

Now this isn’t a traditional plugin, so bear with me. The processing script is called memcache.php, and its content is as follows:

  // note that if you change this variable, the cache restarts!
  $memcache_sectext=md5('mysite'.date('YMd'));
  $memcached=false;

  // display a 'reset this page in cache' link at bottom of page?
  $allowreset=true;

  if (function_exists('memcache_connect')) {
    $memcached=true;
    $memcache=@memcache_connect('127.0.0.1',11211) OR $memcached=false;
  } else {
    $memcached=false;
  }

  function getCache($var_name) {
    global $memcached,$memcache,$memcache_sectext;
    if ($memcached)
      $var_value=$memcache->get($memcache_sectext.'_'.$var_name);
    else
      $var_value='';
    return $var_value;
  }
  function setCache($var_name,$var_value) {
    global $memcached,$memcache,$memcache_sectext;
    if ($memcached)
      $memcache->set($memcache_sectext.'_'.$var_name,$var_value);
  }

  $domain=$_SERVER['HTTP_HOST'];
  $uri=$_SERVER['REQUEST_URI'];

  if ((isset($_GET['recache'])) AND ($allowreset)) {
    setCache($_GET['recache'],'');
    header('location: '.$_GET['recache']);
    exit;
  }

  $html=getCache($uri);
  if ($html!=='caching') {
    if (strlen($html)>100) {
      echo $html;
      if ($allowreset) echo '<p align="center">This page was retrieved'
        .' from our cache. <a href="/memcache.php?recache='
        .urlencode($uri).'" ref="nofollow">Recompile this page</a>.</p>';
      exit;
    } else {
      setCache($uri,'caching');
      $html=file_get_contents('http://'.$domain.$uri);
      if (strlen($html)>100) {
        setCache($uri,$html);
        echo $html;
        if ($allowreset) echo '<p align="center">This page was retrieved'
          .' from our cache. <a href="/memcache.php?recache='
          .urlencode($uri).'" ref="nofollow">Recompile this page</a>.</p>';
        exit;
      } else {
        setCache($uri,'');
      }
    }
  }

I include this file in /index.php, like this:

define('WP_USE_THEMES', true);

include('memcache.php');

/** Loads the WordPress Environment and Template */
require('./wp-blog-header.php');

Any page that is viewed via index.php (that’s posts, category listings, the home page etc.) will be cached and served automatically by memcache.php. Really simple, isn’t it? The cache is reset every day, as to introduce any new content that is dynamic.

It is worth noting that if a cached copy of the requested page is available and served, that WordPress doesn’t even make a connection to the database – NO queries are executed. There is no method faster than this.

The downsides to this method:

  1. When you make a new post or edit an existing post, the changes won’t show up until the next day. To help resolve this, I added an option to reset individual pages in the cache. You can turn the option on and off with the variable $allowreset at the top of the script. The option to reset a page appears at the very end of the page. (I’d recommend disallowing /memcache.php to your robots.txt file too!)
  2. Every page in the cache appears like it would to a guest. Users cannot log in with this method – YET.

I may turn this into an actual plugin, but for now there’s no demand. If you have any comments or suggestions, my ears are wide open!

NOTE: If you were to receive a burst of traffic due to being digg’d or something, I have no doubt that this implementation of Memcached in WordPress would allow your server to take care of it with no problems.

Leave a Reply

Your email address will not be published. Required fields are marked *