A quick tip to cache the result of a function in PHP

Imagine you have a function which computes something, but you need the results of this computation fairly often. For example, imagine this little method to check if a user is has administrative privileges in some web application.

function isAdmin($user_id) {
  return getDatabase()->getOne(sprintf('SELECT id_admin FROM users WHERE user_id = %d', $userid));
}

This is an elegant one-line solution and would work pretty well in a simple application. However, if you use this function in a template to determine what buttons should be shown to a user, the combined output of running this function over and over again will add up quickly if you have more than one administrative button.

You can easily store something inside a function using a so called static variable. This variable will persist when the function ends and will be available when the function is executed again. So, a look at the improved function:

function isAdmin($user_id) {
  static $caches = array();
  if (!isset($caches[$user_id]) {
    $caches[$user_id] = getDatabase()->getOne(sprintf('SELECT id_admin FROM users WHERE user_id = %d', $userid));
  }
  return $caches[$user_id];
}

The function will only execute one database query per $user_id. This can save you a lot of processing, at the cost of storing the results in memory. Don’t do this if you want to store thousands of objects, this will take a lot of memory. Look ups in arrays are fast, because a binary tree index is used to locate the value of an array key.

If you need to share a cache between several functions, you cannot use a static variable because this type of variable is only accessable within the function that defines it. Use a private object property instead.

Feel free to pots any quesions in the comments.


About this entry