A Session backend for Zend_Cache

While building an intranet application I was in need for adding some performance to my user based queries and logic. After considering and discarding to write a stream_wrapper for the session:// space and use if with a File backend, I came across the registry backend by Sameer Parwani, and noticed how fairly easy it was to create a Zend_Cache_Backend.

Using the cache is fairly simple:

$cache = Zend_Cache_Factory('Core', 'My_Application_Cache_Backend_Session', $frontendOptions, $backendOptions, true);

Noteworthy is the 5th parameter, which allows for custom adapter naming, preventing zend framework to go look for Zend_Cache_Backend_My_Application_Cache_Backend_Session.

The code:

<?php

/**
 * A Cache Backend for using {@link Zend_Cache} for caching complex or costly queries and calls
 * which however are related to a specific user's session.
 *
 * Based on Sameer Parwani Registry Backend:
 * @see http://sameerparwani.com/posts/using-zend_registry-as-a-zend_cache-backend/
 */

class My_Application_Cache_Backend_Session extends Zend_Cache_Backend implements Zend_Cache_Backend_Interface{

 /* namespace name for the zend_session_namespace */
 const NAMESPACE_NAME = "cachebackendsession";
 
 /* a static instance of the zend_session_namespace */
 protected static $_namespace;
 
 /**
 * Constructor
 *
 * @param  array $options associative array of options
 * @throws Zend_Cache_Exception
 * @return void
 */

 public function __construct($options = array()) {
     parent::__construct($options);
     // Construct a namespace
     if (!isset(self::$_namespace)) {
      self::$_namespace = new Zend_Session_Namespace(self::NAMESPACE_NAME);
  }
  // Construct a data array
  if(!isset(self::$_namespace->data)) {
   self::$_namespace->data = array();
  }
 }
 /**
 * Test if a cache is available for the given id and (if yes) return it (false else)
 *
 *
 * @param  string  $id                     cache id
 * @param  boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
 * @return string cached datas (or false)
 */

 
 public function load($id, $doNotTestCacheValidity = false){
     
  if (!isset(self::$_namespace->data[$id])) {
      return false;
     }
     
     return self::$_namespace->data[$id];
 }
 
 /**
 * Test if a cache is available or not (for the given id)
 *
 * @param  string $id cache id
 * @return boolean true if exists false if not
 */

 public function test($id) {
     return isset(self::$_namespace->data[$id]);
 }
 
 /**
 * Save some string datas into a cache record
 *
 * Note : $data is always "string" (serialization is done by the
 * core not by the backend)
 *
 * @param string $data datas to cache
 * @param string $id cache id
 * @param array $tags array of strings, the cache record will be tagged by each string entry
 * @param int $specificLifetime if != false, set a specific lifetime for this cache record (null => infinite lifetime)
 * @return boolean true if no problem
 */

 public function save($data, $id, $tags = array(), $specificLifetime = false) {
     self::$_namespace->data[$id] = $data;
     if (count($tags) > 0) {
         $this->_log("Zend_Cache_Backend_Registry::save() : tags are unsupported by the session backend");
     }
     return true;
 }

 /**
 * Remove a cache record
 *
 * @param  string $id cache id
 * @return boolean true if no problem
 */

 public function remove($id) {
     unset(self::$_namespace->data[$id]);
     return true;
 }

 /**
 * Clean some cache records
 *
 * Available modes are :
 * 'all' (default)  => remove all cache entries ($tags is not used)
 * 'old'            => remove too old cache entries ($tags is not used)
 * 'matchingTag'    => remove cache entries matching all given tags
 *                     ($tags can be an array of strings or a single string)
 * 'notMatchingTag' => remove cache entries not matching one of the given tags
 *                     ($tags can be an array of strings or a single string)
 *
 * @param  string $mode clean mode
 * @param  array  $tags array of tags
 * @return boolean true if no problem
 */

 public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) {
     if ($mode==Zend_Cache::CLEANING_MODE_ALL) {
         self::$_namespace->data = array();
     }
     if ($mode==Zend_Cache::CLEANING_MODE_OLD) {
         $this->_log("Zend_Cache_Backend_registry::clean() : CLEANING_MODE_OLD is unsupported by the session backend");
     }
     if ($mode==Zend_Cache::CLEANING_MODE_MATCHING_TAG) {
         $this->_log("Zend_Cache_Backend_registry::clean() : tags are unsupported by the session backend");
     }
     if ($mode==Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG) {
         $this->_log("Zend_Cache_Backend_registry::clean() : tags are unsupported by the session backend");
     }
 }
 
 /**
 * Return true if the automatic cleaning is available for the backend
 *
 * @return boolean
 */

 public function isAutomaticCleaningAvailable() {
     return false;
 }
}  
?>
Be Sociable, Share!

Tags: , ,

Leave a Comment

This blog is kept spam free by WP-SpamFree.