diff --git a/README.md b/README.md index 152277b..50f6b04 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ provide guarantees whether or not the item has been removed from cache. #### getMultiple() -The `getMultiple(string[] $keys, mixed $default = null): PromiseInterface` method can be used to +The `getMultiple(iterable $keys, mixed $default = null): PromiseInterface>` method can be used to retrieve multiple cache items by their unique keys. This method will resolve with an array of cached values on success or with the @@ -142,9 +142,10 @@ Similarly, an expired cache item (once the time-to-live is expired) is considered a cache miss. ```php -$cache->getMultiple(['name', 'age'])->then(function (array $values): void { - $name = $values['name'] ?? 'User'; - $age = $values['age'] ?? 'n/a'; +$cache->getMultiple(['name', 'age'])->then(function (iterable $values): void { + $array = is_array($values) ? $values : iterator_to_array($values); + $name = $array['name'] ?? 'User'; + $age = $array['age'] ?? 'n/a'; echo $name . ' is ' . $age . PHP_EOL; }); @@ -156,7 +157,7 @@ by [promises](https://github.com/reactphp/promise). #### setMultiple() -The `setMultiple(array $values, ?float $ttl = null): PromiseInterface` method can be used to +The `setMultiple(iterable $values, ?float $ttl = null): PromiseInterface` method can be used to persist a set of key => value pairs in the cache, with an optional TTL. This method will resolve with `true` on success or `false` when an error @@ -178,7 +179,7 @@ and the key `bar` to `2`. If some of the keys already exist, they are overridden #### deleteMultiple() -The `setMultiple(string[] $keys): PromiseInterface` method can be used to +The `setMultiple(iterable $keys): PromiseInterface` method can be used to delete multiple cache items in a single operation. This method will resolve with `true` on success or `false` when an error diff --git a/src/ArrayCache.php b/src/ArrayCache.php index d52bee9..4da7860 100644 --- a/src/ArrayCache.php +++ b/src/ArrayCache.php @@ -123,7 +123,7 @@ public function delete(string $key): PromiseInterface return resolve(true); } - public function getMultiple(array $keys, $default = null): PromiseInterface + public function getMultiple(iterable $keys, $default = null): PromiseInterface { $values = []; @@ -135,7 +135,7 @@ public function getMultiple(array $keys, $default = null): PromiseInterface return all($values); } - public function setMultiple(array $values, ?float $ttl = null): PromiseInterface + public function setMultiple(iterable $values, ?float $ttl = null): PromiseInterface { foreach ($values as $key => $value) { $this->set($key, $value, $ttl); @@ -144,7 +144,7 @@ public function setMultiple(array $values, ?float $ttl = null): PromiseInterface return resolve(true); } - public function deleteMultiple(array $keys): PromiseInterface + public function deleteMultiple(iterable $keys): PromiseInterface { foreach ($keys as $key) { unset($this->data[$key], $this->expires[$key]); diff --git a/src/CacheInterface.php b/src/CacheInterface.php index 278108a..2342eaf 100644 --- a/src/CacheInterface.php +++ b/src/CacheInterface.php @@ -106,9 +106,10 @@ public function delete(string $key): PromiseInterface; * considered a cache miss. * * ```php - * $cache->getMultiple(['name', 'age'])->then(function (array $values): void { - * $name = $values['name'] ?? 'User'; - * $age = $values['age'] ?? 'n/a'; + * $cache->getMultiple(['name', 'age'])->then(function (iterable $values): void { + * $array = is_array($values) ? $values : iterator_to_array($values); + * $name = $array['name'] ?? 'User'; + * $age = $array['age'] ?? 'n/a'; * * echo $name . ' is ' . $age . PHP_EOL; * }); @@ -118,11 +119,11 @@ public function delete(string $key): PromiseInterface; * prints some example output. You can use any of the composition provided * by [promises](https://github.com/reactphp/promise). * - * @param string[] $keys A list of keys that can obtained in a single operation. + * @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 PromiseInterface> Returns a promise which resolves to an `array` of cached values + * @return PromiseInterface> Returns a promise which resolves to an `array` of cached values */ - public function getMultiple(array $keys, $default = null): PromiseInterface; + public function getMultiple(iterable $keys, $default = null): PromiseInterface; /** * Persists a set of key => value pairs in the cache, with an optional TTL. @@ -144,19 +145,19 @@ public function getMultiple(array $keys, $default = null): PromiseInterface; * This example eventually sets the list of values - the key `foo` to 1 value * and the key `bar` to 2. If some of the keys already exist, they are overridden. * - * @param array $values A list of key => value pairs for a multiple-set operation. + * @param iterable $values A list of key => value pairs for a multiple-set operation. * @param ?float $ttl Optional. The TTL value of this item. * @return PromiseInterface Returns a promise which resolves to `true` on success or `false` on error */ - public function setMultiple(array $values, ?float $ttl = null): PromiseInterface; + public function setMultiple(iterable $values, ?float $ttl = null): PromiseInterface; /** * Deletes multiple cache items in a single operation. * - * @param string[] $keys A list of string-based keys to be deleted. + * @param iterable $keys A list of string-based keys to be deleted. * @return PromiseInterface Returns a promise which resolves to `true` on success or `false` on error */ - public function deleteMultiple(array $keys): PromiseInterface; + public function deleteMultiple(iterable $keys): PromiseInterface; /** * Wipes clean the entire cache. diff --git a/tests/ArrayCacheTest.php b/tests/ArrayCacheTest.php index e46c726..d37a570 100644 --- a/tests/ArrayCacheTest.php +++ b/tests/ArrayCacheTest.php @@ -164,6 +164,18 @@ public function testGetMultiple(): void ->then($this->expectCallableOnceWith(['foo' => '1', 'bar' => 'baz'])); } + public function testGetMultipleWithIterableKeysFromGenerator(): void + { + $this->cache = new ArrayCache(); + $this->cache->set('foo', '1'); + + $keys = (function (): \Generator { yield from ['foo', 'bar']; })(); + + $this->cache + ->getMultiple($keys, 'baz') + ->then($this->expectCallableOnceWith(['foo' => '1', 'bar' => 'baz'])); + } + public function testSetMultiple(): void { $this->cache = new ArrayCache(); @@ -174,6 +186,18 @@ public function testSetMultiple(): void ->then($this->expectCallableOnceWith(['foo' => '1', 'bar' => '2'])); } + public function testSetMultipleWithIterableValuesFromGenerator(): void + { + $values = (function(): \Generator { yield from ['foo' => '1', 'bar' => '2']; })(); + + $this->cache = new ArrayCache(); + $this->cache->setMultiple($values, 10); + + $this->cache + ->getMultiple(['foo', 'bar']) + ->then($this->expectCallableOnceWith(['foo' => '1', 'bar' => '2'])); + } + public function testDeleteMultiple(): void { $this->cache = new ArrayCache(); @@ -196,6 +220,30 @@ public function testDeleteMultiple(): void ->then($this->expectCallableOnceWith(false)); } + public function testDeleteMultipleWithIterableKeysFromGenerator(): void + { + $this->cache = new ArrayCache(); + $this->cache->setMultiple(['foo' => 1, 'bar' => 2, 'baz' => 3]); + + $keys = (function (): \Generator { yield from ['foo', 'baz']; })(); + + $this->cache + ->deleteMultiple($keys) + ->then($this->expectCallableOnceWith(true)); + + $this->cache + ->has('foo') + ->then($this->expectCallableOnceWith(false)); + + $this->cache + ->has('bar') + ->then($this->expectCallableOnceWith(true)); + + $this->cache + ->has('baz') + ->then($this->expectCallableOnceWith(false)); + } + public function testClearShouldClearCache(): void { $this->cache = new ArrayCache();