Caching beyond the norm in Drupal 7
Caching beyond the norm in Drupal 7Feb 9th 2016
When developing in a drupal centric environment there are two general methods used to cache information on the system in modules, these can be used to persist while a page is loading using drupal static or for a longer periods using cache set and cache get.
I have used some other simple and alternative methods, and from reading notes before the drupal_static function declaration in bootstrap.inc; ways of getting even more efficient caching.
First I’ll address drupal static; it’s explained very neatly on this Lullabot article.
This is not necessarily always required. If you have a simple function in your code that you want to remember, a setting and speed is a must, you can just use a static variable.
function get_a_value($value_name) {
static $function_settings = array();
if (!isset($function_settings[$value_name])) {
//get variable from database and set it to $fetched_value
$function_settings['$value_name'] = $fetched_value;
}
else {
return $function_settings[$value_name];
}
}
The static variable $function_settings stays persistent throughout the execution of your page, and the caching stays localised to your function / module.
Another way to do something similar to above, but to include the drupal_static function, would be to do an advanced drupal_static pattern (this is mentioned in the drupal_static notes).
function user_access($string, $account = NULL) {
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['perm'] = &drupal_static(__FUNCTION__);
}
$perm = &$drupal_static_fast['perm'];
//...
}
This is taken directly from the notes. Here we assign a local static variable as in the previous example but if the local static variable is not set, we assign the local static variable to drupal_static. Now other functions and code outside of the function can call on drupal_static_reset and reset the locally declared static variable, but will still retain the efficiency of having the static variable locally as in the previous example.
The last method I would like to approach is by using a cache in an object:
class SomeClass {
/**
*
* @var array
*/
protected $localCache = array();
public function getData($cid) {
if ($data = $this->getCache($cid)) {
return $data;
}
//nothing set
//do time intensive task here and set to data
$this->cache($cid, $data);
return $data;
}
/**
*
* @param type $cid
* @param type $data
*/
protected function cache($cid, $data) {
$this->setLocalCache($cid, $data);
cache_set($cid, $data, 'cache', strtotime('+7 days', time()));
}
protected function getCache($cid) {
if ($data = $this->getLocalCache($cid)) {
return $data;
}
if ($cache = cache_get($cid)) {
return $cache->data;
}
return FALSE;
}
/**
*
* @param any $cid
* @param any $data
*/
protected function setLocalCache($cid, $data) {
$this->localCache[$cid] = $data;
}
/**
*
* @param any $cid
* @return any
*/
protected function getLocalCache($cid) {
return isset($this->localCache[$cid]) ? $this->localCache[$cid] : FALSE;
}
}
In this example, I do all the local caching within the object but if needs be, I will retrieve and save to the system cache if the required data is not saved locally. One thing I have omitted is methods to clear the local cache. This caching this essentially using a local property.
If you wanted to clear the cache externally, you could create a public method or a static method.
So that about wraps this one up. Have you used any different methods? Can it be done better? Tell me what you think in the comment section below.
Written by: Darren Whittington, Senior Developer
Microserve is a Drupal Agency based in Bristol, UK. We specialise in Drupal Development, Drupal Site Audits and Health Checks, and Drupal Support and Maintenance. Contact us for for further information.