Skip to content

Instantly share code, notes, and snippets.

@geerpm
Created May 16, 2018 11:10
Show Gist options
  • Save geerpm/6ba06bf92f9d785ff11778907f07c5ca to your computer and use it in GitHub Desktop.
Save geerpm/6ba06bf92f9d785ff11778907f07c5ca to your computer and use it in GitHub Desktop.
cakephp3.6 PSR-16(simple cache) adapter with \Cake\Cache\Cache (NO DEBUG)
<?php
/**
* cakephp3.6
* Cache adapter for PSR-16
*
* 1. Add 'psr/simple-cache' to your composer ($ composer.phar require psr/simple-cache)
* 2. Add 'psr16' settings in app.php OR change 'CACHE_ENGINE' constant in PsrSimpleCache class.
*
* 'Cache' => [
* 'psr16' => [
* 'className' => 'Memcached', // or other engine
* // ...
* ],
* ]
*/
namespace App\Cache;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\InvalidArgumentException;
use Cake\Cache\Cache;
class PsrSimpleCache implements CacheInterface
{
const CACHE_ENGINE = 'psr16';
/**
*
*/
public function getCacheEngine()
{
$cacheEngine = Cache::engine(self::CACHE_ENGINE);
return $cacheEngine;
}
/**
* Fetches a value from the cache.
*
* @param string $key The unique key of this item in the cache.
* @param mixed $default Default value to return if the key does not exist.
*
* @return mixed The value of the item from the cache, or $default in case of cache miss.
*
* @throws \Psr\SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function get($key, $default = null)
{
$ret = $this->getCacheEngine()->read($key);
// cake-cache return false if expired or not exist
if ($ret !== false) {
return $ret;
}
return $default;
}
/**
* Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
*
* @param string $key The key of the item to store.
* @param mixed $value The value of the item to store, must be serializable.
* @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
* the driver supports TTL then the library may set a default value
* for it or let the driver take care of that.
*
* @return bool True on success and false on failure.
*
* @throws \Psr\SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function set($key, $value, $ttl = null)
{
return $this->setMultiple([$key => $value], $ttl);
}
/**
* Delete an item from the cache by its unique key.
*
* @param string $key The unique cache key of the item to delete.
*
* @return bool True if the item was successfully removed. False if there was an error.
*
* @throws \Psr\SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function delete($key)
{
// cake-cache return boolean
return $this->getCacheEngine()->delete($key);
}
/**
* Wipes clean the entire cache's keys.
*
* @return bool True on success and false on failure.
*/
public function clear()
{
// clear() 1st arg 'false' means All including available items in that engine
// https://github.com/cakephp/cakephp/blob/master/src/Cache/Cache.php#L492
// cake-cache return boolean
return $this->getCacheEngine()->clear(false);
}
/**
* Obtains multiple cache items by their unique keys.
*
* @param iterable $keys A list of keys that can obtained in a single operation.
* @param mixed $default Default value to return for keys that do not exist.
*
* @return iterable A list of key => value pairs. Cache keys that do not exist or are stale will have $default as value.
*
* @throws \Psr\SimpleCache\InvalidArgumentException
* MUST be thrown if $keys is neither an array nor a Traversable,
* or if any of the $keys are not a legal value.
*/
public function getMultiple($keys, $default = null)
{
$ret = $this->getCacheEngine()->readMany((array)$keys);
// cake-cache return boolean
if ($ret !== false) {
return $ret;
}
return $default;
}
/**
* Persists a set of key => value pairs in the cache, with an optional TTL.
*
* @param iterable $values A list of key => value pairs for a multiple-set operation.
* @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
* the driver supports TTL then the library may set a default value
* for it or let the driver take care of that.
*
* @return bool True on success and false on failure.
*
* @throws \Psr\SimpleCache\InvalidArgumentException
* MUST be thrown if $values is neither an array nor a Traversable,
* or if any of the $values are not a legal value.
*/
public function setMultiple($values, $ttl = null)
{
$cacheEngine = $this->getCacheEngine();
$origDuration = null;
// For change ttl dynamically
if (!is_null($ttl)) {
// Calc php-DateInterval to int (seconds)
if ($ttl instanceof \DateInterval) {
$baseTime = new \DateTimeImmutable();
$endTime = $baseTime->add($ttl);
$ttl = $endTime->getTimestamp() - $baseTime->getTimestamp();
}
// Change ttl if value is ok
if (is_numeric($ttl) && $ttl > 0) {
// Keep original duration
$origDuration = $cacheEngine->getConfig('duration');
// cake-cache accept string as strtotime argument or int value(using as seconds)
$cacheEngine->setConfig('duration', $ttl);
} else {
InvalidArgumentException('Invalid arg "ttl" ');
}
}
$retArr = $cacheEngine->writeMany($data);
// Set back original duration
$cacheEngine->setConfig('duration', $origDuration);
// writeMany return boolean array
$search = false;
if (in_array($search, $retArr, true)) {
// If $retArr has one false, return false
return false;
} else {
return true;
}
}
/**
* Deletes multiple cache items in a single operation.
*
* @param iterable $keys A list of string-based keys to be deleted.
*
* @return bool True if the items were successfully removed. False if there was an error.
*
* @throws \Psr\SimpleCache\InvalidArgumentException
* MUST be thrown if $keys is neither an array nor a Traversable,
* or if any of the $keys are not a legal value.
*/
public function deleteMultiple($keys)
{
// cake-cache return boolean array
$retArray = $this->getCacheEngine()->deleteMany($keys);
$search = false;
if (in_array($search, $retArr, true)) {
return false;
} else {
return true;
}
}
/**
* Determines whether an item is present in the cache.
*
* NOTE: It is recommended that has() is only to be used for cache warming type purposes
* and not to be used within your live applications operations for get/set, as this method
* is subject to a race condition where your has() will return true and immediately after,
* another script can remove it making the state of your app out of date.
*
* @param string $key The cache item key.
*
* @return bool
*
* @throws \Psr\SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function has($key)
{
$ret = $this->getCacheEngine()->read($key);
// If set 'false' to cache, this code can't check that
if ($ret === false) {
return false;
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment