What I've been doing lately is creating a service and then configuring that service with both a db connection and a cache object. Retrieving the data uses a kind of "lazy-loading cascade", looking first in memory, then in cache, then to the db.
For example, one of my apps is for a real-estate agency that operates in several - but not all - of the provinces in our country. We have a db-table of provinces, some of which are enabled for the front-end, and we need to render them in various places (say, as options in a select element). We do something like this (the legacy code-base on which I am working uses DAO objects for db access and PEAR's Cache_Lite for caching, so the example is not strictly Zend Framework, but the principle applies equally):
/**
* A service for fetching provinces
*/
class My_Service_Provinces
{
protected $_daoProvinces;
protected $_provinces = array();
protected $_cache;
public function __construct($daoProvinces)
{
$this->setDaoProvinces($daoProvinces);
}
public function setDaoProvinces($daoProvinces)
{
$this->_daoProvinces = $daoProvinces;
return $this;
}
public function getDaoProvinces()
{
return $this->_daoProvinces;
}
public function setCache($cache)
{
$this->_cache = $cache;
return $this;
}
public function getCache()
{
if (null == $this->_cache){
$this->_cache = new My_Cache_Provinces();
}
return $this->_cache;
}
public function getProvinces()
{
if (null == $this->_provinces){
$cache = $this->getCache();
$data = $cache->get();
if (!$data){
$dao = $this->getDaoProvinces();
$rows = $dao->frontend();
$data = array();
while ($row = $rows->get_row()){
$data[$row['provinceId']] = $row;
}
$cache->save(serialize($data));
} else {
$data = unserialize($data);
}
$this->_provinces = $data;
}
return $this->_provinces;
}
public function getProvince($provinceId)
{
$provinces = $this->getProvinces();
return isset($provinces[$provinceId]) ? $provinces[$provinceId] : null;
}
}
The cache object is pre-configured with whatever lifetime is appropriate. I give a long lifetime to seldom-changing data, shorter lifetimes to frequently-changing data. If I really need the change to the data to be immediately available to the app - say, the admin adds a new province - I instantiate the cache object and clear the cache on update.
I've even added a factory to help instantiate the service so that calling code does not have to sweat the dependencies. Calling code - perhaps in a controller or even in a view or view-helper - looks something like:
$service = My_Service_Factory::getService('provinces');
$provinces = $service->getProvinces();
Knowwhatimsayin'?