WPTip.me

WordPress Development Tutorials & Tips

Exploring the WordPress Cache API

 

WordPress Cache API

WordPress comes with object caching system. That is, it stores data (variables, options, posts, etc.) in a cache so the application doesn’t have to hit the database over and over again for that data.

A great example of this is options. When the first call to get_option is made, WordPress fetches all the options with autoload flag set to ‘yes’, and sticks them into the cache. Subsequent calls to get_option never hit the database.

And, of course, you can use the object cache in your WordPress plugins and themes too! If you have a particularly expensive caculation, store it the cache for later use.

Note: the codex is a bit thin on information for the Cache API beyond a page about the WP_Object_Cache object. You can see the default implementation of all these function in wp-includes/cache.php or here.

Adding Items to the Cache

There are two functions for this: wp_cache_add and wp_cache_set. Both have the same prototype.

<?php
wp_cache_add($key, $data, $group, $expires);

$key is the cache key, and, combined with $group, is used to identify and fetch the cache values later on. $data is the data you wish to store in the given cache key/group. $expires is the length of time the item should reside in the cache. $expires, by default, doesn't matter: the WordPress cache is not persistent by default. It may matter if you use another object cache back end (more on that later).

wp_cache_add will only add an item to the cache if the group/key combination doesn't already exist. Use this only if you don't want to overwrite cache variables. wp_cache_set will set a cache key no matter way. If the above doesn't make sense, just remember that 90% of the time you probably want wp_cache_set.

There is also wp_cache_replace which is functionally the same as wp_cache_set.

Fetching Items from the Cache

wp_cache_get does this. It's prototype:

<?php
wp_cache_get($key, $group, $force=false, &$found=null);

$key and $group are the main items here: they should should correspond with a key/group pair already set in the cache. $force will set the cache key/group combination to false. $found is passed by reference, and will be set to true if the item is found -- this might be useful if your cache value might, for some reason, actually be false.

If a call to wp_cache_get fails, it will return false. So, you can do something like in your plugins/themes:

<?php
if(($res = wp_cache_get('some_key', 'some_group')) !== false)
{
    // cache fetch didn't work
    // generate the result
    $res = 'some_really_expensive_value';
    // set it in the cache for next time
    wp_cache_set('some_key', $res, 'some_group');
}

Or with $found.

<?php
$res = wp_cache_get('some_key', 'some_group', false, $found);
if(!$found)
{
   // do stuff
}

Delete an Item from the Cache

wp_cache_delete does this. It takes the $key and $group. wp_cache_delete will return true if it succeeds and false if it fails.

This isn't particularly useful unless you're using a persistent caching solution. All values get deleted when a page finishes rendering by default.

Incrementing and Decrementing

Say you want to keep track of number of times something happens in a piece of code. Static variables or object properties could work, but if you'd like to share that information use wp_cache_incr.

This is a counter. An example:

<?php

$i = wp_cache_incr('counter', 1, 'some_group');
// $i is 1

// do stuff

$i = wp_cache_incr('counter', 1, 'some_group');
// $i is 2

There's also the reverse: decrement with wp_cache_decr.

Both wp_cache_incr and wp_cache_decr have the same prototype:

<?php
wp_cache_incr($key, $offset=1, $group='');

We're already familiar with $key and $group. $offset is the amount by which to increment or decrement. So if you want to go in jumps of three:

<?php

$i = wp_cache_incr('counter', 3, 'some_group');
// $i is 3

// do stuff

$i = wp_cache_incr('counter', 3, 'some_group');
// $i is 6

wp_cache_incr and wp_cache_decr both return the incremented value.

Other Cache Functions

wp_cache_init and wp_cache_close open and close the cache. wp_cache_init just sets a global variable, $wp_object_cache. wp_cache_close does nothing by default. Using a persistent caching solution, however, might might wp_cache_close more interesting.

wp_cache_reset (deprecated in WordPress 3.5) and wp_cache_flush remove all data from the cache. wp_cache_reset does not remove global group data (see below).

wp_cache_add_global_groups adds, as you might suspect, a global group or groups. You probably don't need to use this. It's useful in a multisite context, where one might want to share cache data between all blogs.

wp_cache_add_non_persistent_groups does nothing by default. WordPress' built in cache does not persist. This is used, however, on persistent caches where you might want to specify things that should never go into the persistent cache.

New in WordPress 3.5 is wp_cache_switch_to_blog. As the name implies, it simply switches the cache to point to a different blog in multisite. Generally this means some stuff is done internally to make sure one cache doesn't overwrite another.

Replacing the Object Cache

The coolest part about the WordPress object cache is that it's replacable. You can use a different cache backend if you so choose. This is done through use of a drop in (of which, there are several).

To replace the object cache, create a file name object-cache.php in your content directory (usually wp-content). From there it's just a matter of defining the functions I listed above and making the behave in a way that suits your needs.

Of course, there are already persistent cache backends written for APC, memcached, and XCache.

Photo by Garrette.