Dec 08
27
A Session backend for Zend_Cache
Leave a comment »
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;
}
}
?>
/**
* 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;
}
}
?>
Related posts: