A Simple Introduction To Zend_Cache

2nd April 2009

The Zend_Cache class is part of the Zend Framework and is used (as its name suggests) to cache things. This can be anything from the front end browser output to the outcome of a complex calculation or even the results of database queries. Zend_Cache is an enormous topic, not just how the class works, but what the best practices are for caching.

The best place to start with caching is one of the simpler topics of caching database queries, from this point you can work on understanding other caching functionality. Normally, a call to a database table in Zend Framework might be done like this.

  1. $houses = new Houses();
  2. $result = $houses->fetchAll();

The result would then be processed. To use Zend_Cache instead of calling the database we first need to set up our Zend_Cache object so that we can use it. To do this we need to call the Zend_Cache static function factory() with a few parameters, which will give us a cache object. Here is a typical example.

$query_cache = Zend_Cache::factory('Core', 'File', $frontendoptions, $backendoptions);

The parameters are as follows:

  • 'Core' - This can be a number of different options which dictate what sort of things are cached on the frontend, the value here is mapped to a class. In this case the class is Zend_Cache_Core, but other classes are mapped to Zend_Cache_Frontend_*. The Zend_Cache_Core class is best used for database calls because there is no specific frontend class that deals with database calls.
  • 'File' - This indicates where the cache is to be stored in the backend. Again this value maps to a class, in this case Zend_Cache_Backend_File. In most cases the Zend_Cache_Backend_File class is the simplest and easiest option to use.
  • $frontendoptions - This is an array of options that relates to the frontend class you have chosen.
  • $backendoptions - This is an array of options that relates to the backend class you have chosen.

The following code sets up an instance of Zend_Cache using some common parameters. Note that different frontend and backend classes have a different set of parameters, but the parameters used below are for the Core frontend and the File backend. The APPLICATION_PATH constant just points to our application folder.

  1. $frontendoptions = array(
  2. 'lifetime' => 60 * 5, // 5minutes
  3. 'automatic_serialization'=>true
  4. );
  5. $backendoptions = array(
  6. 'cache_dir'=> APPLICATION_PATH . '/cache/',
  7. 'file_name_prefix' => 'zend_cache_query',
  8. 'hashed_directory_level' => 2
  9. );
  10. $query_cache = Zend_Cache::factory('Core', 'File', $frontendoptions, $backendoptions);

Here is an explanation of the frontend options used.

  • lifetime - This is self explanatory. If the cache created is greater than the number of seconds for this parameter then the cache is deleted. This can be set to null if we wan't the cache to last forever.
  • automatic_serialization - If set to true this will automatically serialise the cache data. This allows you to store complex data like objects and arrays. If you are storing a numeric value or text string only then you can set this to false.

Here is an explanation of the backend options used.

  • cache_dir - This is the directory that the cache is to be kept in. The default to this is /tmp/ but it is best to keep the cache within the application folder so that you can manage the files manually if need be.
  • file_name_prefix - This sets the start of the filename to be used, because I want to cache database queries I have selected zend_cache_query as my prefix.
  • hashed_directory_level - Some file systems have great difficulty handling lots of files in a single directory. This option splits the cache into different levels or directories. The default is 0, but for this example I have selected 2. This means that our cache files will be stored inside 2 levels of directories.

To load a cache we use the load() function. This function takes a parameter that identifies the cache, but because we are getting all data from the houses table we don't need to worry too much about this. If there is no cache with that name present then the function returns false. If this occurs we run our normal database query but in each case the $result variable will contain our data.

  1. if ( !($result = $query_cache->load('allhouses')) ) {
  2. $houses = new Houses();
  3. $result = $houses->fetchAll();
  4. $query_cache->save($result, 'allhouses');
  5. }

Once we have run the normal query we save the result to the cache using the save() function. This contains the data we want to save in the first parameter and the same cache name as the load() function in the second parameter. The next time the page is loaded the cache is loaded instead of calling the database.

We can also cache single data rows in the same way by using a unique identifier for our cache name. Assuming that have our house id we can do the following:

  1. $cacheName = 'house'.$id;
  2. if ( !($result = $query_cache->load($cacheName )) ) {
  3. $houses = new Houses();
  4. $result = $houses->fetchRow($houses->select()->where('id = ?', $id));
  5. $query_cache->save($result, $cacheName );
  6. }

Note that if you want to do anything more than display the results of the query then you will need to access the database directly. It is not possible to interact with a database through the cached object.

Add new comment

The content of this field is kept private and will not be shown publicly.