Zend Framework 2 Cache Proxy – Cache Based Key Dependency.

July 5, 2014

Long time no ZF2 post, but here is something interesting peace of code that can solve cache problems present in most of the projects.

I am assuming that, the reader knows how to create custom cache Factory in ZF2.

Step 1.

Edit your existing cache factory.

See Line 35.

namespace Application\Factory;

use Application\Factory\CacheProxy; // Or whatever location
use Zend\Cache\Storage\Plugin\Serializer;
use Zend\Cache\StorageFactory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class CacheFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $sm)
    {
        $config = $sm->get('config');

        $cache = StorageFactory::factory(array(
                    'adapter' => array(
                        'name' => 'filesystem',
                    ),
                    'plugins' => array(
                        // Don't throw exceptions on cache errors
                        'exception_handler' => array(
                            'throw_exceptions' => true
                        ),
                    )
        ));

        if (!file_exists($config['cache']['cache_dir'])) {
            mkdir($config['cache']['cache_dir'], 0755, true);
        }

        $cache->getOptions()->setTtl((int) $config['cache']['cache_ttl']);
        $cache->getOptions()->setCacheDir($config['cache']['cache_dir']);
        $cache->addPlugin(new Serializer);

        return new CacheProxy($cache);
    }
}

Step 2.

CacheProxy Code

namespace Application\Factory;

use Zend\Cache\Storage\StorageInterface;

class CacheProxy
{
    /**
     *
     * @var \Zend\Cache\Storage\StorageInterface
     */
    protected $cache;

    /**
     * We are using the fact that $key is the first parameter
     * and pass by reference is not present.
     * @var type 
     */
    protected $override = [
        'hasItem',
        'getMetadata',
        'setItem',
        'addItem',
        'replaceItem',
        'touchItem',
        'removeItem',
        'incrementItem',
        'decrementItem'
    ];

    public function __construct(StorageInterface $cache)
    {
        $this->cache = $cache;
    }

    /**
     * 
     * @param type $name
     * @param type $arguments
     * @return type
     */
    public function __call($name, $arguments)
    {
        if (in_array($name, $this->override)) {
            $arguments[0] = $this->getKey($arguments[0]);
        }
        $return = call_user_func_array([$this->cache, $name], $arguments);
        /**
         * Ensure that chain calls will work as expected.
         */
        if ($return instanceof StorageInterface) {
            return new self($return);
        } else {
            return $return;
        }
    }

    /**
     * 
     * @param type $key
     * @param type $success
     * @param type $casToken
     */
    public function getItem($key, &$success = null, &$casToken = null)
    {
        return $this->cache->getItem($this->getKey($key), $success, $casToken);
    }

    /**
     * @param type $token
     * @param type $key
     * @param type $value
     * @return type
     */
    public function checkAndSetItem($token, $key, $value)
    {
        return $this->cache->replaceItem($token, $this->getKey($key), $value);
    }

    /**
     * 
     * @param type $key
     * @return type
     */
    protected function getKey($key)
    {
        return sha1(
            sprintf(
                '%s-%s-%s',
                $key,
                defined('APPLICATION_ENV')     ? APPLICATION_ENV : '',
                defined('APPLICATION_VERSION') ? APPLICATION_VERSION : ''
            )
        );
    }
}

Simple as that.

Suggestions or problems ? Write a comment.

tags: ,
posted in OOP, Zend Framework 2 by Ivan Gospodinow

Follow comments via the RSS Feed | Leave a comment | Trackback URL

Leave Your Comment

 
 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org