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.