Cache the model

recently began the task to organize caching of data. And it turned out very handy thing. Implementation see under jabracada...

Described below is an abstract class to put our models in the folder Cache. In my case it is /Default/Models/Cache/Abstract.php

the
abstract class Default_Models_Cache_Abstract
{
protected static $_cache;
protected static $_staticCache;
protected static $_tags = null;
protected static $_className = null;
protected static $_nonCachedMethods = array();

protected static $_frontendName;
protected static $_backendName;
protected static $_frontendOptions = array();
protected static $_backendOptions = array();

public  function  __construct()
{
static::$_cache = null;
static::$_staticCache = null;
static::_init();
}

public function __call($name, $arguments)
{
return static::_call($name, $arguments);
}

public static function __callStatic($name, $arguments)
{
return static::_call($name, $arguments, true);
}

protected static function _call($name, $arguments, $useStatic = false)
{
static::_init($useStatic);
$cache = $useStatic ? static::$_staticCache : static::$_cache;
if (in_array($name, static::$_nonCachedMethods)) {
return call_user_func_array(array($cache, $name), $arguments);
}
$id = $cache- > makeId($name, $arguments);
if (!($result = $cache->load($id))) {
$result = $cache->__call($name, $arguments);
$cache->save($result, $id, static::$_tags);
}
return $result;
}

protected static function _initConfig()
{
static $inited = null;
if (null === $inited) {
if (null === static::$_className) {
throw new Exception("You must provide a <code>protected static"
. "\$_className = ...;</code> statement in your class!");
}
static::$_backendName = 'File';
static::$_frontendName = 'class';
static::$_frontendOptions = array();
static::$_backendOptions = array();
$inited = true;
}
}

protected static function _init($useStatic = false)
{
$ref = null;
if ($useStatic && null === static::$_staticCache) {
$ref = static::$_className;
} elseif (null === static::$_cache) {
if (!class_exists(static::$_className)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass(static::$_className);
}
$ref = new static::$_className;
}
if (null !== $ref) {
static::_initConfig();
static::$_tags = array(static::$_className);
static::$_frontendOptions['cached_entity'] = $ref;
if (!empty(static::$_nonCachedMethods)) {
static::$_frontendOptions['non_cached_methods']
= is_array(static::$_nonCachedMethods)
? static::$_nonCachedMethods
: array(static::$_nonCachedMethods);
}
$cache = Zend_Cache::factory(
static::$_frontendName,
static::$_backendName,
static::$_frontendOptions,
static::$_backendOptions
);
if ($useStatic) {
static::$_staticCache = $cache;
} else {
static::$_cache = $cache;
}
}
}

public function cleanCache()
{
$ids = static::$_cache->getIdsMatchingTags();
foreach($ids as $id) {
static::$_cache- > remove($id);
}
static::$_cache- > clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, static::$_tags);
}
}

To work you must have a working model, for example Default_Models_Products.
In Cache folder, relative to ' file our model, create a class Default_Models_Cache_Products with the following properties $_className and $_nonCachedMethods:
the
class extends Default_Models_Cache_Products Default_Models_Cache_Abstract
{
protected static $_className = 'Default_Models_Products';
protected static $_nonCachedMethods = array('addProduct');
}

$_className name of the cached class. $_nonCachedMethods not a required property, in this we list those methods which we do not need to be cached.

All references to the class Default_Models_Products replace Default_Models_Cache_Products work with him as with Default_Models_Products.
For example, in our model implemented getList.
the
class Default_Models_Products
{
...
public function getList()
{
...
return $list;
}
...
}

To obtain data we can in the following way:
the
$productsModel = new Default_Models_Cache_Products();
$productList = $productsModel->getList();

Also implemented the ability to call static methods. If getList is a static
the
class Default_Models_Products
{
...
public static function getList()
{
...
return $list;
}
...
}

cause it will be like this:
the
$productList = Default_Models_Cache_Products::getList();

To clear the cache implemented method cleanCache(), its call will be made to clear the cache specific to this model that can be very useful.

About the job parameters $_frontendOptions and $_backendOptions you can read here and here

The class is highly versatile and is suitable not only for models.

PS Clarification. Thanks to Victor(Yeah) for the tip, this class is will not work in versions of php below 5.3. Since the magic method __callStatic() was introduced with this version of php.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Automatically create Liquibase migrations for PostgreSQL

Looking for books as you want

Vkontakte sync with address book for iPhone. How it was done