Secondary menu

Using Drupal Cache In Your Custom Module For Better Performance

nrussell's picture

Using Drupal Cache In Your Custom Module For Better Performance

Written by Nick Russell on

I am actually quite surprised that more developers aren't aware of the power of the cache_set and cache_get functions than most. So I thought I'd take a second today to speak to when you would want to leverage these functions and how they works. So lets start with a scenario.

The Poorly Coded, Memory Intensive Array

We've all seen it before. The insane iteration that does a crap ton of logic and builds out an expensive array at the cost of your websites performance. Now, the most obvious solution would be to rework the code so it performs more friendly, but what if your code has already been reworked and is still taking too long to execute? Cache It! Lets take a look at a basic example:

// Load all of the node titles from Drupal.
$node_titles = array();
$query = db_select("node", "n")
  ->fields("n", array("title"))
  ->execute();
while ($result = $query->fetchAssoc()) {
  $node_titles[] = $result['title'];
}

It doesn't take an experienced programmer to know that this little query right here can get expensive really quick. Sure, the developer has taken the right steps in loading only the title and not doing a node_load() every iteration, but when the DB grows, more nodes get added or more fields become required in the query, the expense of this running on every page is costly. So why not let it run the first time (assuming your php memory settings can handle it) and cache the results for future retrieval?

// Load all of the node titles from Drupal. Lets assume there are over 100,000 nodes.
$cache_id = "uniqueue_cache_key";
$node_titles = cache_get($cache_id, 'cache');
if (empty($node_titles)) {
  $node_titles = array();
  $query = db_select("node", "n")
    ->fields("n", array("title"))
    ->execute();
  while ($result = $query->fetchAssoc()) {
    $node_titles[] = $result['title'];
  }
  cache_set($cache_id, $node_titles, 'cache', CACHE_PERMANENT);
}

What we've just done is let Drupal execute the query and set the $node_titles array if no cached version was retrieved. Then we cache the results. Now, the next time this code is run, we can pull the cached results in and serve them without having to make another run through the same logic. Get the idea?!

But How Do I Update The Cache?

Simple! You can write logic anywhere in your application that clears a particular cache based on the cache key so you can reset it with new data. For example:

if ($some_condition) {
  cache_clear_all('uniqueue_cache_key', 'cache');
}
 
// Do your logic, rebuild the array and recache the results!

When Drupal caches data in this fashion, it does nothing more than store the values being passed into it into a serialized array in the database. Obviously, you don't want to cache everything in your entire application. There are other technologies for that. But if you have pieces of your application that do consume a large amount of memory to calculate the same results over and over again, this is a great tool to have in your back pocket! See the documentation here for more information.