A caching pattern for models
Tags: web-development, zend framework, patterns, caching, php
Паттерн кэширования для моделей
Паттерн кешування для моделей
| ← Automated Testing Using Zend Framework | Advanced Debugging with JavaScript → |
This is a caching pattern for models using Zend_Cache and the __call magic method.
The Basic Idea
The initial thought behind this is that a model should be able to return calls either uncached or cached, without initializing some cache object every time. It should be easy to switch between the two calls, and the cache should be coming with the model object already.
The old way
Before introducing the cache pattern, I would create an object that then would use Zend_Cache_Frontend_Class, then initialize a new instance of my model in there, then redefine a method that acts as somewhat like a proxy, but uses the cache. And if that wasn't enough, I'd have to initialize them both, like in this example:
Hide code highlighting
The new way
So Matthias asked me: Would it not be nicer if the cache was already available in the model, and you could do something like this:
Hide code highlighting
A great idea. As you can see this proposed way saves a bit of code, it's intuitive and easy to change, if you ever need to switch between cached and non-cached calls.
The Code
First we need to create an object that initializes the cache. We'll initialize a cache with Zend_Cache and then utilize the __call function to check whether a call exists in the cached object or not. This enables us to only do valid calls.
Hide code highlighting
The second step is to create a base model class, that we'll use for all our models. It will initialize the cache object using the BaseModelCache and make it available as public property:
Hide code highlighting
Et Voilà! Now we can create models by extending the BaseModel. The cache will be available as described above.
Original: A caching pattern for models
The Basic Idea
The initial thought behind this is that a model should be able to return calls either uncached or cached, without initializing some cache object every time. It should be easy to switch between the two calls, and the cache should be coming with the model object already.
The old way
Before introducing the cache pattern, I would create an object that then would use Zend_Cache_Frontend_Class, then initialize a new instance of my model in there, then redefine a method that acts as somewhat like a proxy, but uses the cache. And if that wasn't enough, I'd have to initialize them both, like in this example:
Hide code highlighting
1 2 3 4 5 6 | $model = MyModel(); $model_cached = MyModelCached(); $values_direct = $model->doStuff(); $values_cached = $model_cached->doStuff(); |
The new way
So Matthias asked me: Would it not be nicer if the cache was already available in the model, and you could do something like this:
Hide code highlighting
1 2 3 4 | $model = MyModel(); $values_direct = $model->doStuff(); $values_cached = $model->cache->doStuff(); |
A great idea. As you can see this proposed way saves a bit of code, it's intuitive and easy to change, if you ever need to switch between cached and non-cached calls.
The Code
First we need to create an object that initializes the cache. We'll initialize a cache with Zend_Cache and then utilize the __call function to check whether a call exists in the cached object or not. This enables us to only do valid calls.
Hide code highlighting
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | class BaseModelCache { private $object; private $cache; public function __construct($object) { $backendName = 'File'; $frontendName = 'Class'; $frontendOptions = array( 'lifetime' => 1800, ); $backendOptions = array( 'cache_dir' => '/my/cache/dir/', ); $this->object = $object; $frontendOptions['cached_entity'] = $object; try { Zend_Loader::loadClass('Zend_Cache'); $this->cache = Zend_Cache::factory($frontendName, $backendName, $frontendOptions, $backendOptions); } catch(Exception $e) { throw($e); } } public function __call($method, $args) { $class = get_class($this->object); $class_methods = get_class_methods($class); if(in_array($method , $class_methods)) { $caller = Array($this->cache, $method); return call_user_func_array($caller, $args); } throw new Exception( " Method " . $method . " does not exist in this class " . get_class($class ) . "." ); } } |
The second step is to create a base model class, that we'll use for all our models. It will initialize the cache object using the BaseModelCache and make it available as public property:
Hide code highlighting
1 2 3 4 5 6 7 8 | abstract class BaseModel { public $cache; public function __construct() { $this->cache = new BaseModelCache($this); } } |
Et Voilà! Now we can create models by extending the BaseModel. The cache will be available as described above.
Original: A caching pattern for models
Rating:




<< Please, rate this articleRelated articles:
6 Tools To Be An Effective Web Developer
Understanding scope in object oriented JavaScript
An Introduction to the Art of Unit Testing in PHP
Integrating FCKeditor with Zend_Form
Automated Testing Using Zend Framework