Drupal 7 cache bins, why and how to?
As you work on larger and more complex Drupal projects you’ll quickly realise that you really need to start thinking about the performance of the site.
One easy (relatively, anyway) way is to use Drupal’s cache bins. Cache bins are quite great for situations where you need to do heavy calculations, and/or a heavy set of database queries, and you need to do them often, but the data won’t change all too often.
So how does one go about implementing your very own cache bin?
Creating a custom cache bin
You can of course use one of Drupal’s existing cache tables, but I prefer to create my own to keep things more organised, and for the ability to clear that cache separately.
So in your custom module you’d do something like:
/**
* Implements hook_schema().
*/
function exove_module_schema() {
$schema = array();
$schema['cache_exove_module'] = drupal_get_schema_unprocessed('system', 'cache');
return $schema;
}
/**
* Implements hook_flush_caches().
*/
function exove_module_flush_caches() {
return array('cache_exove_module');
}
Setting and getting data from the cache bin
So let’s say you have some function that does a lot of heavy lifting, and you don’t want to bog down your server by calling it all the time, especially if that data will only change under certain conditions (for example after certain time, or after certain nodes have been created / updated / deleted, etc.).
There are two commands that you’ll be using for this:
cache_set
https://api.drupal.org/api/drupal/includes%21cache.inc/function/cache_set/7cache_get
https://api.drupal.org/api/drupal/includes%21cache.inc/function/cache_get/7.
/**
* A function that does a lot of crazy computation
*/
function exove_module_function() {
$data = &drupal_static(__FUNCTION__);
if(!isset($data)) {
if($cache = cache_get('CACHE_ID', 'cache_exove_module')) {
$data = $cache->data;
}
else {
// This is where you would place your code that does all the heavy lifting
// ... code
// And once that is done, you want to save the data into the cache
cache_set('CACHE_ID', $data, 'cache_exove_module');
}
}
return $data;
}
A note about CACHE_ID
in the above example code. This can be anything you want, for example it can be just a string, or if the cache is different for each user then you could include the user’s UID in the name.
Or say it’s data that is specific to nodes, so you’d use something like (provided of course that you have the $node object available):
cache_set('node_cache_' . $node->nid, $data, 'cache_exove_module');
Clearing the cache
Clearing cache is as simple as having this in your code then:
cache_clear_all('*', 'cache_exove_module', true);
And you can use that wherever you need it, be it in a helper function or a node hook, where ever you like really.
If you want to set a specific time for the cache to expire, you can provide a third parameter for the cache_set() call. The choices are CACHE_PERMANENT
, CACHE_TEMPORARY
or a Unix timestamp.
Drush and cache bins
If you use drush (and as a Drupal developer there’s no reason why you shouldn’t), you should also create a file called for example exovemod.drush.inc
inside your module directory, and in that file you’ll want to have something like:
/**
* Implements hook_drush_cache_clear().
*/
function exovemod_drush_cache_clear(&$types) {
$types['exove_module'] = '_exove_module_cache_clear';
}
/**
* Utility function that clears all the entries in our cache bin.
*/
function _exove_module_cache_clear() {
cache_clear_all('*', 'cache_exove_module', true);
}
Share on social media: