PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Zend Framework 101: Zend_Cache

How Caching Works

There are three fundamental concepts when implementing a caching solution:

  1. Adding data to the cache
  2. Serving data from the cache
  3. Clearing data from the cache

When you request data from a cache and it is found, this is called a "cache hit". If the data is not found this is a "cache miss". When using a cache there are two basic objectives:

  1. Minimize cache misses (the data you want should nearly always be in cache already if possible)
  2. Never serve stale data (if the caller gets incorrect or outdated data then so what if it came back quickly?)

Adding Data To The Cache

Typically adding data to the cache and serving from the cache are combined into a single step. The algorithm for this is as follows:

  1. Caller requests some data from the cache
  2. Data in cache? Return it to the caller
  3. Not found in cache? Generate the data, save it to the cache, return it to the caller.

While this is typically straightforward to implement, you must be aware that the first caller will suffer the penalty of generating the data. To counter this, you can "prime" the cache ahead of time. This is typically implemented by one or more scripts that are automatically run (such as in a cron job). These scripts are stubs that generate all of the data and save it into the cache so it will be available upon request.

Later in this article we'll also looked at tagging cache records. You can specifiy any number of tags when saving a record to the cache which will help you identify the record later.

Also worth mentioning is that cache records have a lifetime associated with them. This is the amount of time that the data can be trusted before we assume it's no longer valid. You can specify a default lifetime when creating a cache, and you can also override this value on a per-record basis. Zend_Cache will automatically manage the lifetime and clearing of expired cache records.

Serving Data From The Cache

In order to serve data from the cache, you must determine which data is being requested. When using Zend_Cache, every unique resource has its own cache identifier.

Once the identifier is known you request the corresponding data from the cache. To create an identifer you use the input data that helps determine the data being generated.

The following listing demonstrates this at the most basic level. It assumes you have one set of navigation for logged-in users and a different navigation for users that aren't logged in.

Listing 1 Generating a cache ID (listing-1.php)
<?php
    if ($userIsLoggedIn) {
        $cacheId = 'navloggedin';
    }
    else {
        $cacheId = 'navnotloggedin';
    }
 
    // get data from cache with the ID $cacheId
?>

Typically the cache ID will be dynamically generated using other data, such as GET/POST data or function arguments. The following listing shows an example of how you might generate a cache ID based on arguments passed to a function.

Listing 2 Generating a more complex cache ID (listing-2.php)
<?php
    function someFunction($options)
    {
        $cacheId = md5(serialize(func_get_args()));
 
        // get data from cache with the ID $cacheId
    }
 
    $options = array(
        'foo' => 'bar'
    );
 
    $response = someFunction($options);
?>
Tip: You can only use a-z, A-Z, 0-9 and underscores in your cache ID. If you're using complex data to generate the cache ID, simply use md5() to generate a compatible ID.

Clearing Data From The Cache

One of the primary goals listed above was that the user should never be served stale data (unless it is acceptable to do so). This goal is achieved by clearing the cache when dependent data is updated.

Let's use my company's Content Management System (Recite CMS) as an example. One of the most expensive operations when displaying a page in Recite CMS is to generate the web site navigation. It is also an extremely important aspect that we want to maximise performance for. Because of this, we cache as much of this data as we can.

If a content editor creates a new page on their web site, they expect for that new page to appear in the web site navigation. Therefore, when they create the new page, in the background we must clear the cached navigation data.

There are two ways to approach clearing data from the cache:

  1. Clear the entire cache
  2. Clear the related cache records

Ideally you will only clear the related cache records (this is where tagging the cache records becomes useful!), but on occasion it can be difficult to isolate the records so the "brute force" approach of clearing the entire cache is required.

Later in this article we will look at how to remove cache records when using Zend_Cache.

Now that we've covered the theory of caching, let's move on to actually implementing a Zend_Cache-based solution.

In This Article