Easily manage Zend_Cache with a custom PHP Class

December 13th 2012

Caching dynamic content is a very good way of speeding up your Web Applications. Obviously there is some data that can't be cached but generally you can cache even small amounts of data for a minute if it'll help speed up the execution of your application.

It won't come as a surprise that I use Zend_Cache for my caching, but I've put the grunt work into an external class. I try (wherever possible) to keep my controllers lean.

This is a very easy to use class. I've included 4 examples under the code for you to see how things tick.

You can specify a cache expiration time by calling:

PHP Code:
<?php
new App_Cache_File($identifier,3600); // would cache for 1 hour

Here's the class you need:

PHP Code:
<?php
class App_Cache_File {

    
/**
     *
     * @var string
     */
    
private $identifier null;

    
/**
     * Temporary storage for data
     * @var mixed dependant on what's actually stored.
     */
    
private $data;

    
/**
     *
     * @var Zend_Cache_Core
     */
    
private $cache;

    
/**
     *
     * @var boolean
     */
    
private $has false;

    
/**
     *
     * @var integer
     */
    
private $lifetime 10;

    
/**
     *
     * @var boolean
     */
    
private $wasValidConstruct false;

    
/**
     * Initialise the class by giving a unique identifier.
     * @param string $identifier
     * @param integer $lifetime how long the cache should live in seconds.
     */
    
public function __construct($identifier$lifetime 10)
    {
        if (!
is_numeric($lifetime))
        {
            
$lifetime 10;
        }
        else
        {
            
$this->lifetime = (int)$lifetime;
        }

        if (
null == $identifier || empty($identifier))
        {
            
$this->wasValidConstruct false;
            
$this->has false;
        }
        else
        {
            
$this->wasValidConstruct true;
            
$this->identifier $identifier;
        }

        
$this->setup();
    }

    
/**
     * Sets up the Cache.
     */
    
protected function setup()
    {

        
$front = array(
            
'automatic_cleaning_factor' => 1,
            
'automatic_serialization' => true,
            
'lifetime' => $this->lifetime
        
);

        
$back = array(
            
'cache_dir' => sys_get_temp_dir(),
        );

        try {
            
$this->cache Zend_Cache::factory('Core''File'$front$back);

            if (!
$this->wasValidConstruct)
            {
                
// we break hear to allow the class to also run
                // the destroy process
                
return;
            }

            if (
null != ($this->data $this->cache->load($this->identifier)))
            {
                
$this->has true;
            }
        } catch (
Exception $e) {
            
$this->has false;
            
$this->cache null;
            
$this->wasValidConstruct false;
        }

        return;
    }

    
/**
     * Check if a cache exists by the given Id.
     * @return boolean
     */
    
public function hasCache()
    {
        return 
$this->has;
    }

    
/**
     * Return the cache.
     * @return boolean false for no cache|mixed for cache content
     */
    
public function getCache()
    {
        if (!
$this->hasCache())
        {
            return 
false;
        }

        if (
null == $this->data)
        {
            return 
false;
        }

        return 
$this->data;
    }

    
/**
     * Give almost any variable type and put it into cache.
     * @param mixed $data
     * @return mixed whatever goes into the class regardless of save state.
     */
    
public function cache($data)
    {
        if (!
$this->wasValidConstruct)
        {
            
// Construct wasnt valid so we wont even attempt it.
            
return $data;
        }

        try {
            
$saved $this->cache->save($data$this->identifier);
            if (!
$saved)
            {
                
trigger_error("Unable to save cache.");
            }
        } catch (
Exception $e) {
            
trigger_error($e->getMessage());
            
$saved false;
        }

        return 
$data;
    }

    
/**
     * Remove an item from cache.
     * @return boolean true if removal was a success.
     */
    
public function remove()
    {
        if (!
$this->wasValidConstruct)
        {
            
// We dont have a valid Cache Identifier
            
return false;
        }
        try {
            
$status $this->cache->remove($this->identifier);
        } catch (
Exception $e) {
            
trigger_error($e->getMessage());
            
$status false;
        }
        return 
$status;
    }

    
/**
     * Destroys the entire cache.
     * @return NULL
     */
    
public function destroy()
    {
        try {
            
$ids $this->cache->getIds();
            foreach (
$ids as $id) {
                
$this->cache->remove($id);
            }
        } catch (
Exception $e) {
            
trigger_error($e->getMessage());
        }
        return;
    }
}

Caching an Object in PHP

PHP Code:
<?php
$cacher 
= new App_Cache_File('cache_identifier_1');
if (!
$cacher->hasCache()) {
    
// Not in cache
    
$object = new stdClass();
    
$object->name "Joe Bloggs";
    
$object->age 32;
    
$data $cacher->cache($object);
}
else {
    
// From Cache
    
$data $cacher->getCache();
}
var_dump($data);
// object(stdClass)#5 (2) {
//   ["name"]=>
//   string(10) "Joe Bloggs"
//   ["age"]=>
//   int(32)
// }

Caching a string in PHP

PHP Code:
<?php
$cacher 
= new App_Cache_File('cache_identifier_2');
if (!
$cacher->hasCache()) {
    
// Not in cache
    
$string "The quick brown fox jumped over the lazy dog.";
    
$data $cacher->cache($string);
}
else {
    
// From Cache
    
$data $cacher->getCache();
}
var_dump($data);
// string(45) "The quick brown fox jumped over the lazy dog."

Caching an integer in PHP

PHP Code:
<?php
$cacher 
= new App_Cache_File('cache_identifier_3');
if (!
$cacher->hasCache()) {
    
// Not in cache
    
$integer 123456;
    
$data $cacher->cache($integer);
}
else {
    
// From Cache
    
$data $cacher->getCache();
}
var_dump($data);
// int(123456)

Caching an array in PHP

PHP Code:
<?php
$cacher 
= new App_Cache_File('cache_identifier_4');
if (!
$cacher->hasCache()) {
    
// Not in cache
    
$array = array('name' => 'Joe Bloggs''age' => 32);
    
$data $cacher->cache($array);
}
else {
    
// From Cache
    
$data $cacher->getCache();
}
var_dump($data);
// array(2) {
//   ["name"]=>
//   string(10) "Joe Bloggs"
//   ["age"]=>
//   int(32)
// }

And that's about it! Enjoy your caching.