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.