diff --git a/composer.json b/composer.json index 858c316f..691de1c2 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,23 @@ "type": "library", "keywords": [ "cache", - "psr6" + "psr6", + "psr-6", + "php-cache", + "cache-adapter", + "caching", + "apcu", + "redis", + "memcached", + "mongodb", + "mysql", + "doctrine-cache", + "predis", + "file-cache", + "memcache", + "session-cache", + "serverside-cache", + "php" ], "authors": [ { diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index ad3eca1f..efd8e5a8 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -12,6 +12,7 @@ namespace Cache\Adapter\Memcached; use Cache\Adapter\Common\AbstractCachePool; +use Cache\Adapter\Common\Exception\InvalidArgumentException; use Cache\Adapter\Common\PhpCacheItem; use Cache\Adapter\Common\TagSupportWithArray; use Cache\Hierarchy\HierarchicalCachePoolTrait; @@ -45,13 +46,124 @@ public function __construct(\Memcached $cache) */ protected function fetchObjectFromCache($key) { - if (false === $result = unserialize($this->cache->get($this->getHierarchyKey($key)))) { + $value = $this->cache->get($this->getHierarchyKey($key)); + if (false === $result = (is_array($value) ? $value : unserialize($value))) { return [false, null, [], null]; } return $result; } + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + if (!is_array($keys)) { + if (!$keys instanceof \Traversable) { + throw new InvalidArgumentException('$keys is neither an array nor Traversable'); + } + // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. + $keys = iterator_to_array($keys, false); + } + $items = []; + foreach ($keys as $key) { + $this->validateKey($key); + $items[] = $this->getHierarchyKey($key); + } + if (defined('\Memcached::GET_EXTENDED') === false) { + $null = null; + $results = $this->cache->getMulti($items, $null, \Memcached::GET_PRESERVE_ORDER); + } else { + $results = $this->cache->getMulti($items, \Memcached::GET_PRESERVE_ORDER); + } + /** + * @param $default + * @param $items + * @param $results + * @param $keys + * + * @return \Generator + */ + $return = function ($default, $items, $results, $keys) { + foreach ($keys as $idx => $key) { + $value = (false === $return[$key] = (isset($results[$items[$idx]]) ? (is_array($results[$items[$idx]]) ? $results[$items[$idx]] : unserialize($results[$items[$idx]])) : false)) ? $default : $return[$key][1]; + yield $key => $value; + } + }; + + return $return($default, $items, $results, $keys); + } + + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + if (!is_array($values)) { + if (!$values instanceof \Traversable) { + throw new InvalidArgumentException('$values is neither an array nor Traversable'); + } + } + $keys = []; + $arrayValues = []; + foreach ($values as $key => $value) { + if (is_int($key)) { + $key = (string) $key; + } + $this->validateKey($key); + $keys[] = $key; + $arrayValues[$key] = $value; + } + $items = $this->getItems($keys); + $itemSuccess = true; + $set = []; + foreach ($items as $key => $item) { + $item->expiresAfter($ttl); + $set[$this->getHierarchyKey($key)] = [true, $arrayValues[$key], $item->getTags(), $item->getExpirationTimestamp()]; + } + if ($ttl instanceof \DateInterval) { + $ttl = $ttl->format('%s'); + } elseif ($ttl instanceof \DateTimeInterface) { + $ttl = $ttl->getTimestamp() - time(); + } + if (is_numeric($ttl)) { + $ttl = intval($ttl); + if ($ttl <= (86400 * 30)) { + $ttl++; + } + } + $itemSuccess = $this->cache->setMulti($set, $ttl); + + return $itemSuccess; + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + if (!method_exists('\Memcached', 'deleteMulti')) { + return parent::deleteMultiple($keys); + } + if (!is_array($keys)) { + if (!$keys instanceof \Traversable) { + throw new InvalidArgumentException('$keys is neither an array nor Traversable'); + } + // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. + $keys = iterator_to_array($keys, false); + } + $items = []; + foreach ($keys as $key) { + $this->validateKey($key); + $items[] = $this->getHierarchyKey($key); + } + $this->cache->deleteMulti($items); + + return true; + //return $this->deleteItems($keys); + } + /** * {@inheritdoc} */