From 1a257ff93ef8203fe041a5f1b08be1b6dcf67073 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Tue, 9 Jan 2024 16:31:10 -0600 Subject: [PATCH 1/7] PHP 8.1 Implementation --- .github/workflows/phpunit.yml | 3 +- composer.json | 11 ++++--- src/CacheAvailabilityInterface.php | 2 +- src/CacheLockInterface.php | 4 +-- src/Factory.php | 14 ++++----- src/Psr16/ArrayCacheEngine.php | 25 +++++++++------ src/Psr16/BaseCacheEngine.php | 39 +++++++++++++++-------- src/Psr16/FileSystemCacheEngine.php | 16 +++++----- src/Psr16/MemcachedEngine.php | 12 +++---- src/Psr16/NoCacheEngine.php | 17 +++++----- src/Psr16/RedisCacheEngine.php | 14 +++++---- src/Psr16/SessionCacheEngine.php | 19 +++++++---- src/Psr16/ShmopCacheEngine.php | 14 +++++---- src/Psr6/CacheItem.php | 34 ++++++++++---------- src/Psr6/CachePool.php | 49 +++++++++++++++-------------- 15 files changed, 155 insertions(+), 118 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 22bba59..9908d55 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -16,10 +16,9 @@ jobs: strategy: matrix: php-version: + - "8.3" - "8.2" - "8.1" - - "8.0" - - "7.4" # Service containers to run services: diff --git a/composer.json b/composer.json index 4b10ed7..084073c 100644 --- a/composer.json +++ b/composer.json @@ -7,10 +7,10 @@ } }, "require": { - "php": ">=7.4", - "psr/cache": "^1.0", - "psr/log": "^1.1", - "psr/simple-cache": "^1.0", + "php": ">=8.1", + "psr/cache": "^1.0|^2.0|^3.0", + "psr/log": "^1.1|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", "psr/container": "^2.0" }, "require-dev": { @@ -18,7 +18,8 @@ }, "suggest": { "ext-memcached": "*", - "ext-redis": "*" + "ext-redis": "*", + "ext-shmop": "*" }, "license": "MIT" } diff --git a/src/CacheAvailabilityInterface.php b/src/CacheAvailabilityInterface.php index 9e66d23..a954805 100644 --- a/src/CacheAvailabilityInterface.php +++ b/src/CacheAvailabilityInterface.php @@ -9,5 +9,5 @@ interface CacheAvailabilityInterface * Return if this CacheEngine is available for use * @return bool */ - public function isAvailable(); + public function isAvailable(): bool; } diff --git a/src/CacheLockInterface.php b/src/CacheLockInterface.php index 0fecb31..e6ce2aa 100644 --- a/src/CacheLockInterface.php +++ b/src/CacheLockInterface.php @@ -14,11 +14,11 @@ interface CacheLockInterface * Lock resource before set it. * @param string $key */ - public function lock($key); + public function lock(string $key): void; /** * Unlock resource * @param string $key */ - public function unlock($key); + public function unlock(string $key): void; } diff --git a/src/Factory.php b/src/Factory.php index 074e3b5..4b9f74f 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -13,14 +13,14 @@ class Factory { - public static function createNullPool() + public static function createNullPool(): CachePool { return new CachePool( new NoCacheEngine() ); } - public static function createSessionPool($prefix = null, $bufferSize = null) + public static function createSessionPool($prefix = null, $bufferSize = null): CachePool { return new CachePool( new SessionCacheEngine($prefix), @@ -28,7 +28,7 @@ public static function createSessionPool($prefix = null, $bufferSize = null) ); } - public static function createFilePool($prefix = null, $path = null, $bufferSize = null, $logger = null) + public static function createFilePool($prefix = null, $path = null, $bufferSize = null, $logger = null): CachePool { return new CachePool( new FileSystemCacheEngine($prefix, $path, $logger), @@ -36,7 +36,7 @@ public static function createFilePool($prefix = null, $path = null, $bufferSize ); } - public static function createShmopPool($config = [], $bufferSize = null, $logger = null) + public static function createShmopPool($config = [], $bufferSize = null, $logger = null): CachePool { return new CachePool( new ShmopCacheEngine($config, $logger), @@ -44,7 +44,7 @@ public static function createShmopPool($config = [], $bufferSize = null, $logger ); } - public static function createArrayPool($bufferSize = null, $logger = null) + public static function createArrayPool($bufferSize = null, $logger = null): CachePool { return new CachePool( new ArrayCacheEngine($logger), @@ -52,7 +52,7 @@ public static function createArrayPool($bufferSize = null, $logger = null) ); } - public static function createMemcachedPool($servers = null, $bufferSize = null, $logger = null) + public static function createMemcachedPool($servers = null, $bufferSize = null, $logger = null): CachePool { return new CachePool( new MemcachedEngine($servers, $logger), @@ -60,7 +60,7 @@ public static function createMemcachedPool($servers = null, $bufferSize = null, ); } - public static function createRedisCacheEngine($servers = null, $password = null, $bufferSize = null, $logger = null) + public static function createRedisCacheEngine($servers = null, $password = null, $bufferSize = null, $logger = null): CachePool { return new CachePool( new RedisCacheEngine($servers, $password, $logger), diff --git a/src/Psr16/ArrayCacheEngine.php b/src/Psr16/ArrayCacheEngine.php index b86c8fb..43486aa 100644 --- a/src/Psr16/ArrayCacheEngine.php +++ b/src/Psr16/ArrayCacheEngine.php @@ -2,7 +2,10 @@ namespace ByJG\Cache\Psr16; +use ByJG\Cache\Exception\InvalidArgumentException; use DateInterval; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; use Psr\Log\NullLogger; class ArrayCacheEngine extends BaseCacheEngine @@ -29,10 +32,11 @@ public function __construct($logger = null) * * @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. + * @throws InvalidArgumentException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface */ - public function has($key) + public function has(string $key): bool { $key = $this->getKeyFromContainer($key); if (isset($this->cache[$key])) { @@ -51,9 +55,11 @@ public function has($key) * @param string $key The object KEY * @param mixed $default IGNORED IN MEMCACHED. * @return mixed Description - * @throws \Psr\SimpleCache\InvalidArgumentException + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface */ - public function get($key, $default = null) + public function get(string $key, mixed $default = null): mixed { if ($this->has($key)) { $key = $this->getKeyFromContainer($key); @@ -78,7 +84,7 @@ public function get($key, $default = null) * * MUST be thrown if the $key string is not a legal value. */ - public function set($key, $value, $ttl = null) + public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool { $key = $this->getKeyFromContainer($key); @@ -92,9 +98,10 @@ public function set($key, $value, $ttl = null) return true; } - public function clear() + public function clear(): bool { $this->cache = []; + return true; } /** @@ -103,7 +110,7 @@ public function clear() * @param string $key * @return bool */ - public function delete($key) + public function delete(string $key): bool { $key = $this->getKeyFromContainer($key); @@ -112,7 +119,7 @@ public function delete($key) return true; } - public function isAvailable() + public function isAvailable(): bool { return true; } diff --git a/src/Psr16/BaseCacheEngine.php b/src/Psr16/BaseCacheEngine.php index f558e99..360991f 100644 --- a/src/Psr16/BaseCacheEngine.php +++ b/src/Psr16/BaseCacheEngine.php @@ -6,7 +6,9 @@ use ByJG\Cache\Exception\InvalidArgumentException; use DateInterval; use DateTime; +use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; use Psr\SimpleCache\CacheInterface; abstract class BaseCacheEngine implements CacheInterface, CacheAvailabilityInterface @@ -14,16 +16,17 @@ abstract class BaseCacheEngine implements CacheInterface, CacheAvailabilityInter protected ?ContainerInterface $container; /** - * @param $keys + * @param string|iterable $keys * @param null $default - * @return array|iterable + * @return iterable * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function getMultiple($keys, $default = null) + public function getMultiple(string|iterable $keys, mixed $default = null): iterable { - if (!is_array($keys)) { - throw new InvalidArgumentException('getMultipleKeys expected an array'); + if (is_string($keys)) { + $keys = [$keys]; } + $result = []; foreach ($keys as $key) { $result[$key] = $this->get($key, $default); @@ -34,31 +37,33 @@ public function getMultiple($keys, $default = null) /** * @param iterable $values * @param null $ttl - * @return bool|void + * @return bool * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function setMultiple($values, $ttl = null) + public function setMultiple(iterable $values, $ttl = null): bool { foreach ($values as $key => $value) { $this->set($key, $value, $ttl); } + return true; } /** * @param iterable $keys - * @return bool|void + * @return bool * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function deleteMultiple($keys) + public function deleteMultiple(iterable $keys): bool { foreach ($keys as $key) { $this->delete($key); } + return true; } - abstract public function isAvailable(); + abstract public function isAvailable(): bool; - protected function addToNow($ttl) + protected function addToNow(DateInterval|int|null $ttl): int|null { if (is_numeric($ttl)) { return strtotime("+$ttl second"); @@ -73,7 +78,10 @@ protected function addToNow($ttl) return null; } - protected function convertToSeconds($ttl) + /** + * @throws InvalidArgumentException + */ + protected function convertToSeconds(DateInterval|int $ttl) { if (empty($ttl) || is_numeric($ttl)) { return $ttl; @@ -87,7 +95,12 @@ protected function convertToSeconds($ttl) } - protected function getKeyFromContainer($key) + /** + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface + */ + protected function getKeyFromContainer(string $key): mixed { if (empty($this->container)) { return $key; diff --git a/src/Psr16/FileSystemCacheEngine.php b/src/Psr16/FileSystemCacheEngine.php index 819ab11..3dc8b05 100644 --- a/src/Psr16/FileSystemCacheEngine.php +++ b/src/Psr16/FileSystemCacheEngine.php @@ -32,7 +32,7 @@ public function __construct($prefix = 'cache', $path = null, $logger = null) * @return mixed Description * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function get($key, $default = null) + public function get(string $key, mixed $default = null): mixed { // Check if file is Locked $fileKey = $this->fixKey($key); @@ -78,7 +78,7 @@ public function get($key, $default = null) * * MUST be thrown if the $key string is not a legal value. */ - public function set($key, $value, $ttl = null) + public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool { $fileKey = $this->fixKey($key); @@ -119,7 +119,7 @@ public function set($key, $value, $ttl = null) * @return bool * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function delete($key) + public function delete(string $key): bool { $this->set($key, null); return true; @@ -129,7 +129,7 @@ public function delete($key) * Lock resource before set it. * @param string $key */ - public function lock($key) + public function lock(string $key): void { $this->logger->info("[Filesystem cache] Lock '$key'"); @@ -146,7 +146,7 @@ public function lock($key) * UnLock resource after set it. * @param string $key */ - public function unlock($key) + public function unlock($key): void { $this->logger->info("[Filesystem cache] Unlock '$key'"); @@ -158,7 +158,7 @@ public function unlock($key) } } - public function isAvailable() + public function isAvailable(): bool { return is_writable(dirname($this->fixKey('test'))); } @@ -178,7 +178,7 @@ protected function fixKey($key) * * @return bool True on success and false on failure. */ - public function clear() + public function clear(): bool { $patternKey = $this->fixKey('*'); $list = glob($patternKey); @@ -200,7 +200,7 @@ public function clear() * @throws \Psr\SimpleCache\InvalidArgumentException * MUST be thrown if the $key string is not a legal value. */ - public function has($key) + public function has(string $key): bool { $fileKey = $this->fixKey($key); if (file_exists($fileKey)) { diff --git a/src/Psr16/MemcachedEngine.php b/src/Psr16/MemcachedEngine.php index af9eb6f..e382b6b 100644 --- a/src/Psr16/MemcachedEngine.php +++ b/src/Psr16/MemcachedEngine.php @@ -65,7 +65,7 @@ protected function lazyLoadMemCachedServers() * @return mixed Description * @throws StorageErrorException */ - public function get($key, $default = null) + public function get(string $key, mixed $default = null): mixed { $this->lazyLoadMemCachedServers(); @@ -85,7 +85,7 @@ public function get($key, $default = null) * @return bool If the object is successfully posted * @throws StorageErrorException */ - public function set($key, $value, $ttl = null) + public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool { $this->lazyLoadMemCachedServers(); @@ -105,7 +105,7 @@ public function set($key, $value, $ttl = null) * @return bool * @throws StorageErrorException */ - public function delete($key) + public function delete(string $key): bool { $this->lazyLoadMemCachedServers(); @@ -113,7 +113,7 @@ public function delete($key) return true; } - public function isAvailable() + public function isAvailable(): bool { if (!class_exists('\Memcached')) { return false; @@ -131,7 +131,7 @@ public function isAvailable() * @return bool * @throws StorageErrorException */ - public function clear() + public function clear(): bool { $this->lazyLoadMemCachedServers(); $result = $this->memCached->flush(); @@ -143,7 +143,7 @@ public function clear() * @return bool * @throws StorageErrorException */ - public function has($key) + public function has(string $key): bool { $this->lazyLoadMemCachedServers(); diff --git a/src/Psr16/NoCacheEngine.php b/src/Psr16/NoCacheEngine.php index f4af906..f453a62 100644 --- a/src/Psr16/NoCacheEngine.php +++ b/src/Psr16/NoCacheEngine.php @@ -3,6 +3,7 @@ namespace ByJG\Cache\Psr16; use ByJG\Cache\CacheLockInterface; +use DateInterval; class NoCacheEngine extends BaseCacheEngine implements CacheLockInterface { @@ -11,7 +12,7 @@ class NoCacheEngine extends BaseCacheEngine implements CacheLockInterface * @param int $default IGNORED IN MEMCACHED. * @return mixed Description */ - public function get($key, $default = null) + public function get(string $key, mixed $default = null): mixed { $key = $this->getKeyFromContainer($key); return $default; @@ -23,7 +24,7 @@ public function get($key, $default = null) * @param int $ttl The time to live in seconds of this objects * @return bool If the object is successfully posted */ - public function set($key, $value, $ttl = 0) + public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool { $key = $this->getKeyFromContainer($key); return true; @@ -33,7 +34,7 @@ public function set($key, $value, $ttl = 0) * @param string $key * @return bool */ - public function delete($key) + public function delete(string $key): bool { $key = $this->getKeyFromContainer($key); return true; @@ -43,7 +44,7 @@ public function delete($key) * Lock resource before set it. * @param string $key */ - public function lock($key) + public function lock(string $key): void { return; } @@ -52,12 +53,12 @@ public function lock($key) * UnLock resource after set it * @param string $key */ - public function unlock($key) + public function unlock(string $key): void { return; } - public function isAvailable() + public function isAvailable(): bool { return true; } @@ -67,7 +68,7 @@ public function isAvailable() * * @return bool True on success and false on failure. */ - public function clear() + public function clear(): bool { return true; } @@ -84,7 +85,7 @@ public function clear() * @throws \Psr\SimpleCache\InvalidArgumentException * MUST be thrown if the $key string is not a legal value. */ - public function has($key) + public function has(string $key): bool { $key = $this->getKeyFromContainer($key); return false; diff --git a/src/Psr16/RedisCacheEngine.php b/src/Psr16/RedisCacheEngine.php index ff896a8..2b1089d 100644 --- a/src/Psr16/RedisCacheEngine.php +++ b/src/Psr16/RedisCacheEngine.php @@ -2,6 +2,7 @@ namespace ByJG\Cache\Psr16; +use DateInterval; use Psr\Log\NullLogger; class RedisCacheEngine extends BaseCacheEngine @@ -60,7 +61,7 @@ protected function fixKey($key) { * @param int $default IGNORED IN MEMCACHED. * @return mixed Description */ - public function get($key, $default = null) + public function get(string $key, mixed $default = null): mixed { $this->lazyLoadRedisServer(); @@ -76,7 +77,7 @@ public function get($key, $default = null) * @param int $ttl The time to live in seconds of this objects * @return bool If the object is successfully posted */ - public function set($key, $value, $ttl = null) + public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool { $this->lazyLoadRedisServer(); @@ -88,7 +89,7 @@ public function set($key, $value, $ttl = null) return true; } - public function delete($key) + public function delete(string $key): bool { $this->lazyLoadRedisServer(); @@ -97,7 +98,7 @@ public function delete($key) return true; } - public function clear() + public function clear(): bool { $keys = $this->redis->keys('cache:*'); foreach ((array)$keys as $key) { @@ -105,9 +106,10 @@ public function clear() $this->delete($matches['key']); } } + return true; } - public function has($key) + public function has(string $key): bool { $result = $this->redis->exists($this->fixKey($key)); @@ -118,7 +120,7 @@ public function has($key) return $result; } - public function isAvailable() + public function isAvailable(): bool { if (!class_exists('\Redis')) { return false; diff --git a/src/Psr16/SessionCacheEngine.php b/src/Psr16/SessionCacheEngine.php index 9c5fa01..cde9588 100644 --- a/src/Psr16/SessionCacheEngine.php +++ b/src/Psr16/SessionCacheEngine.php @@ -2,6 +2,8 @@ namespace ByJG\Cache\Psr16; +use DateInterval; + class SessionCacheEngine extends BaseCacheEngine { @@ -31,7 +33,7 @@ protected function keyName($key) return $this->prefix . '-' . $key; } - public function get($key, $default = null) + public function get(string $key, mixed $default = null): mixed { $this->checkSession(); @@ -44,7 +46,7 @@ public function get($key, $default = null) } } - public function delete($key) + public function delete(string $key): bool { $this->checkSession(); @@ -56,9 +58,11 @@ public function delete($key) if (isset($_SESSION["$keyName.ttl"])) { unset($_SESSION["$keyName.ttl"]); } + + return true; } - public function set($key, $value, $ttl = null) + public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool { $this->checkSession(); @@ -67,14 +71,17 @@ public function set($key, $value, $ttl = null) if (!empty($ttl)) { $_SESSION["$keyName.ttl"] = $this->addToNow($ttl); } + + return true; } - public function clear() + public function clear(): bool { session_destroy(); + return true; } - public function has($key) + public function has(string $key): bool { $keyName = $this->keyName($key); @@ -90,7 +97,7 @@ public function has($key) return false; } - public function isAvailable() + public function isAvailable(): bool { try { $this->checkSession(); diff --git a/src/Psr16/ShmopCacheEngine.php b/src/Psr16/ShmopCacheEngine.php index 5fd1528..91f5844 100644 --- a/src/Psr16/ShmopCacheEngine.php +++ b/src/Psr16/ShmopCacheEngine.php @@ -4,6 +4,7 @@ use ByJG\Cache\Exception\InvalidArgumentException; use ByJG\Cache\Exception\StorageErrorException; +use DateInterval; use Psr\Log\NullLogger; /** @@ -73,7 +74,7 @@ protected function getFTok($file) * @param mixed $default The time to live in seconds of the object. Depends on implementation. * @return mixed The Object */ - public function get($key, $default = null) + public function get(string $key, mixed $default = null): mixed { if ($default === false) { $this->logger->info("[Shmop Cache] Ignored $key because TTL=FALSE"); @@ -129,7 +130,7 @@ protected function isValidAge($file) * @throws InvalidArgumentException * @throws StorageErrorException */ - public function set($key, $value, $ttl = null) + public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool { $this->logger->info("[Shmop Cache] set '$key'"); @@ -173,7 +174,7 @@ public function set($key, $value, $ttl = null) * @param string $key * @return bool */ - public function delete($key) + public function delete(string $key): bool { $this->logger->info("[Shmop Cache] release '$key'"); @@ -208,16 +209,17 @@ private function deleteFromFilenameToken($file) } } - public function clear() + public function clear(): bool { $patternKey = sys_get_temp_dir() . '/shmop-*.cache'; $list = glob($patternKey); foreach ($list as $file) { $this->deleteFromFilenameToken($file); } + return true; } - public function has($key) + public function has(string $key): bool { $file = $this->getFilenameToken($key); $fileKey = $this->getFTok($file); @@ -236,7 +238,7 @@ public function has($key) } - public function isAvailable() + public function isAvailable(): bool { return function_exists('shmop_open'); } diff --git a/src/Psr6/CacheItem.php b/src/Psr6/CacheItem.php index 6f4aaa9..fa809d6 100644 --- a/src/Psr6/CacheItem.php +++ b/src/Psr6/CacheItem.php @@ -12,22 +12,22 @@ class CacheItem implements CacheItemInterface /** * @var string */ - protected $key; + protected string $key; /** * @var mixed */ - protected $value; + protected mixed $value; /** * @var boolean */ - protected $hit; + protected bool $hit; /** * @var DateTime */ - protected $expiration; + protected DateTimeInterface $expiration; /** * CacheItem constructor. @@ -35,7 +35,7 @@ class CacheItem implements CacheItemInterface * @param mixed $value * @param bool $hit */ - public function __construct($key, $value, $hit = true) + public function __construct(string $key, mixed $value, bool $hit = true) { $this->key = $key; $this->value = $value; @@ -46,7 +46,7 @@ public function __construct($key, $value, $hit = true) /** * {@inheritdoc} */ - public function getKey() + public function getKey(): string { return $this->key; } @@ -54,14 +54,14 @@ public function getKey() /** * {@inheritdoc} */ - public function get() + public function get(): mixed { return $this->isHit() ? $this->value : null; } /** * {@inheritdoc} */ - public function set($value = null) + public function set(mixed $value = null): static { $this->value = $value; $this->hit = !is_null($value); @@ -70,25 +70,27 @@ public function set($value = null) /** * {@inheritdoc} */ - public function isHit() + public function isHit(): bool { return $this->hit; } /** * {@inheritdoc} */ - public function expiresAt($expiration) + public function expiresAt(?DateTimeInterface $expiration): static { - $this->expiration = new DateTime('now +1 year'); - if ($expiration instanceof DateTimeInterface) { - $this->expiration = $expiration; + if (empty($expiration)) { + $this->expiration = new DateTime('now +1 year'); + return $this; } + + $this->expiration = $expiration; return $this; } /** * {@inheritdoc} */ - public function expiresAfter($time) + public function expiresAfter(int|\DateInterval|null $time): static { $this->expiration = new DateTime('now +1 year'); if (is_numeric($time)) { @@ -104,12 +106,12 @@ public function expiresAfter($time) /** * @return DateTime */ - public function getExpiresAt() + public function getExpiresAt(): DateTime { return $this->expiration; } - public function getExpiresInSecs() + public function getExpiresInSecs(): int { return $this->getExpiresAt()->getTimestamp() - (new DateTime('now'))->getTimestamp(); } diff --git a/src/Psr6/CachePool.php b/src/Psr6/CachePool.php index 8ae88a4..9bf5d25 100644 --- a/src/Psr6/CachePool.php +++ b/src/Psr6/CachePool.php @@ -6,33 +6,34 @@ use ByJG\Cache\Psr16\BaseCacheEngine; use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemPoolInterface; +use Psr\SimpleCache\CacheInterface; class CachePool implements CacheItemPoolInterface { /** - * @var \Psr\SimpleCache\CacheInterface + * @var CacheInterface */ - protected $_cacheEngine; + protected CacheInterface $_cacheEngine; /** * @var CacheItem */ - protected $_lastCacheItem; + protected CacheItem $_lastCacheItem; /** * @var int */ - protected $bufferSize = 10; + protected int $bufferSize = 10; /** * @var CacheItem[] */ - protected $buffer = []; + protected array $buffer = []; /** * @var array */ - protected $bufferKeys = []; + protected array $bufferKeys = []; /** * CachePool constructor. @@ -40,16 +41,16 @@ class CachePool implements CacheItemPoolInterface * @param BaseCacheEngine $_cacheEngine * @param int $bufferSize */ - public function __construct(BaseCacheEngine $_cacheEngine, $bufferSize = 10) + public function __construct(BaseCacheEngine $_cacheEngine, int $bufferSize = 10) { $this->_cacheEngine = $_cacheEngine; - $this->bufferSize = intval($bufferSize); + $this->bufferSize = $bufferSize; } /** * @return int */ - public function getBufferSize() + public function getBufferSize(): int { return $this->bufferSize; } @@ -57,7 +58,7 @@ public function getBufferSize() /** * @param int $bufferSize */ - public function setBufferSize($bufferSize) + public function setBufferSize(int $bufferSize): void { $this->bufferSize = $bufferSize; } @@ -68,7 +69,7 @@ public function setBufferSize($bufferSize) * * @param CacheItem $cacheItem */ - protected function addElementToBuffer(CacheItem $cacheItem) + protected function addElementToBuffer(CacheItem $cacheItem): void { if ($this->bufferSize < 1) { return; @@ -94,7 +95,7 @@ protected function addElementToBuffer(CacheItem $cacheItem) * * @param $key */ - protected function removeElementFromBuffer($key) + protected function removeElementFromBuffer(string $key): void { $result = array_search($key, $this->bufferKeys); if ($result === false) { @@ -113,7 +114,7 @@ protected function removeElementFromBuffer($key) * @throws \Psr\SimpleCache\InvalidArgumentException * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function getItem($key) + public function getItem(string $key): CacheItemInterface { // Get the element from the buffer if still remains valid! if (in_array($key, $this->bufferKeys)) { @@ -139,7 +140,7 @@ public function getItem($key) * @return array * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function getItems(array $keys = array()) + public function getItems(array $keys = array()): iterable { $result = []; foreach ($keys as $key) { @@ -156,7 +157,7 @@ public function getItems(array $keys = array()) * @return bool * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function hasItem($key) + public function hasItem(string $key): bool { return $this->getItem($key)->isHit(); } @@ -164,10 +165,11 @@ public function hasItem($key) /** * Psr implementation of clear() */ - public function clear() + public function clear(): bool { $this->bufferKeys = []; $this->buffer = []; + return true; } /** @@ -177,7 +179,7 @@ public function clear() * @return bool * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function deleteItem($key) + public function deleteItem(string $key): bool { return $this->deleteItems([$key]); } @@ -190,7 +192,7 @@ public function deleteItem($key) * @throws \Psr\SimpleCache\InvalidArgumentException * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function deleteItems(array $keys) + public function deleteItems(array $keys): bool { foreach ($keys as $key) { $this->_cacheEngine->delete($key); @@ -205,7 +207,7 @@ public function deleteItems(array $keys) * @return bool * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function save(CacheItemInterface $item) + public function save(CacheItemInterface $item): bool { if (!($item instanceof CacheItem)) { throw new InvalidArgumentException('The cache item must be an implementation of \ByJG\Cache\Psr\CacheItem'); @@ -224,7 +226,7 @@ public function save(CacheItemInterface $item) /** * @var CacheItem[] */ - protected $deferredItem = []; + protected array $deferredItem = []; /** * Psr Implementation of saveDeferred() @@ -232,7 +234,7 @@ public function save(CacheItemInterface $item) * @param CacheItemInterface $item * @return bool */ - public function saveDeferred(CacheItemInterface $item) + public function saveDeferred(CacheItemInterface $item): bool { $this->deferredItem[] = $item; return true; @@ -243,16 +245,17 @@ public function saveDeferred(CacheItemInterface $item) * * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function commit() + public function commit(): bool { foreach ($this->deferredItem as $item) { $this->save($item); } $this->deferredItem = []; + return true; } - public function isAvailable() + public function isAvailable(): bool { return $this->_cacheEngine->isAvailable(); } From fc50089815f01e30c9f4baf12c3ae44a03a4b126 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Wed, 10 Apr 2024 16:18:07 -0500 Subject: [PATCH 2/7] Fix Type convertToSeconds() --- src/Psr16/BaseCacheEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Psr16/BaseCacheEngine.php b/src/Psr16/BaseCacheEngine.php index 360991f..bb59e7b 100644 --- a/src/Psr16/BaseCacheEngine.php +++ b/src/Psr16/BaseCacheEngine.php @@ -81,7 +81,7 @@ protected function addToNow(DateInterval|int|null $ttl): int|null /** * @throws InvalidArgumentException */ - protected function convertToSeconds(DateInterval|int $ttl) + protected function convertToSeconds(DateInterval|int|null $ttl): DateInterval|int|null { if (empty($ttl) || is_numeric($ttl)) { return $ttl; From 74ea968d3708a3f8c88c148cb9199f5e997080b2 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Thu, 23 May 2024 13:06:09 -0500 Subject: [PATCH 3/7] Update Composer --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 084073c..3fae7d3 100644 --- a/composer.json +++ b/composer.json @@ -9,9 +9,9 @@ "require": { "php": ">=8.1", "psr/cache": "^1.0|^2.0|^3.0", - "psr/log": "^1.1|^2.0|^3.0", - "psr/simple-cache": "^1.0|^2.0|^3.0", - "psr/container": "^2.0" + "psr/log": "^1.0|^1.1|^2.0", + "psr/simple-cache": "^1.0|^2.0", + "psr/container": "^1.0|^1.1|^2.0" }, "require-dev": { "phpunit/phpunit": "5.7.*|7.4.*|^9.5" From dd801097163e8d7bacf2b07c23d7b72fa3a9f421 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Wed, 11 Sep 2024 21:04:37 -0500 Subject: [PATCH 4/7] Add Types --- .github/FUNDING.yml | 3 ++ .github/workflows/phpunit.yml | 1 + .run/PHPUnit.run.xml | 6 +++ .run/PSalm.run.xml | 5 ++ composer.json | 7 ++- psalm.xml | 18 +++++++ src/Psr16/ArrayCacheEngine.php | 7 +-- src/Psr16/BaseCacheEngine.php | 14 ++--- src/Psr16/FileSystemCacheEngine.php | 41 +++++++++++---- src/Psr16/MemcachedEngine.php | 44 ++++++++++++---- src/Psr16/NoCacheEngine.php | 33 ++++++++---- src/Psr16/RedisCacheEngine.php | 81 ++++++++++++++++++++++------- src/Psr16/SessionCacheEngine.php | 27 ++++++++-- src/Psr16/ShmopCacheEngine.php | 39 ++++++++++---- src/Psr6/CachePool.php | 4 +- tests/BaseCacheTest.php | 4 +- tests/BasicContainer.php | 2 + tests/CachePSR16Test.php | 26 ++++----- tests/CachePSR6Test.php | 4 +- tests/Model.php | 7 +-- 20 files changed, 267 insertions(+), 106 deletions(-) create mode 100644 .github/FUNDING.yml create mode 100644 .run/PHPUnit.run.xml create mode 100644 .run/PSalm.run.xml create mode 100644 psalm.xml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..3a9251f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +github: byjg diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 9908d55..6dda630 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -36,6 +36,7 @@ jobs: - uses: actions/checkout@v4 - run: composer install - run: ./vendor/bin/phpunit --stderr + - run: ./vendor/bin/psalm Documentation: if: github.ref == 'refs/heads/master' diff --git a/.run/PHPUnit.run.xml b/.run/PHPUnit.run.xml new file mode 100644 index 0000000..7034700 --- /dev/null +++ b/.run/PHPUnit.run.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.run/PSalm.run.xml b/.run/PSalm.run.xml new file mode 100644 index 0000000..bd119ce --- /dev/null +++ b/.run/PSalm.run.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/composer.json b/composer.json index f7ac5f3..0f6630b 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,11 @@ "ByJG\\Cache\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } + }, "require": { "php": ">=8.1", "psr/cache": "^1.0|^2.0|^3.0", @@ -15,7 +20,7 @@ }, "require-dev": { "phpunit/phpunit": "^9.6", - "vimeo/psalm": "^6.0" + "vimeo/psalm": "^5.9" }, "suggest": { "ext-memcached": "*", diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..ebabb1a --- /dev/null +++ b/psalm.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/Psr16/ArrayCacheEngine.php b/src/Psr16/ArrayCacheEngine.php index 865674d..67aa01f 100644 --- a/src/Psr16/ArrayCacheEngine.php +++ b/src/Psr16/ArrayCacheEngine.php @@ -6,16 +6,17 @@ use DateInterval; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; +use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; class ArrayCacheEngine extends BaseCacheEngine { - protected $cache = array(); + protected array $cache = []; - protected $logger = null; + protected LoggerInterface|null $logger = null; - public function __construct($logger = null) + public function __construct(LoggerInterface|null $logger = null) { $this->logger = $logger; if (is_null($logger)) { diff --git a/src/Psr16/BaseCacheEngine.php b/src/Psr16/BaseCacheEngine.php index bb59e7b..0c10629 100644 --- a/src/Psr16/BaseCacheEngine.php +++ b/src/Psr16/BaseCacheEngine.php @@ -17,8 +17,8 @@ abstract class BaseCacheEngine implements CacheInterface, CacheAvailabilityInter /** * @param string|iterable $keys - * @param null $default - * @return iterable + * @param mixed $default + * @return iterable * @throws \Psr\SimpleCache\InvalidArgumentException */ public function getMultiple(string|iterable $keys, mixed $default = null): iterable @@ -36,11 +36,11 @@ public function getMultiple(string|iterable $keys, mixed $default = null): itera /** * @param iterable $values - * @param null $ttl + * @param DateInterval|int|null $ttl * @return bool * @throws \Psr\SimpleCache\InvalidArgumentException */ - public function setMultiple(iterable $values, $ttl = null): bool + public function setMultiple(iterable $values, DateInterval|int|null $ttl = null): bool { foreach ($values as $key => $value) { $this->set($key, $value, $ttl); @@ -87,11 +87,7 @@ protected function convertToSeconds(DateInterval|int|null $ttl): DateInterval|in return $ttl; } - if ($ttl instanceof DateInterval) { - return $ttl->days*86400 + $ttl->h*3600 + $ttl->i*60 + $ttl->s; - } - - throw new InvalidArgumentException('Invalid TTL'); + return $ttl->days*86400 + $ttl->h*3600 + $ttl->i*60 + $ttl->s; } diff --git a/src/Psr16/FileSystemCacheEngine.php b/src/Psr16/FileSystemCacheEngine.php index 3dc8b05..b5b2d0f 100644 --- a/src/Psr16/FileSystemCacheEngine.php +++ b/src/Psr16/FileSystemCacheEngine.php @@ -5,17 +5,21 @@ use ByJG\Cache\CacheLockInterface; use DateInterval; use Exception; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; +use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; +use Psr\SimpleCache\InvalidArgumentException; class FileSystemCacheEngine extends BaseCacheEngine implements CacheLockInterface { - protected $logger = null; + protected ?LoggerInterface $logger = null; - protected $prefix = null; - protected $path = null; + protected ?string $prefix = null; + protected ?string $path = null; - public function __construct($prefix = 'cache', $path = null, $logger = null) + public function __construct(string $prefix = 'cache', ?string $path = null, ?LoggerInterface $logger = null) { $this->prefix = $prefix; $this->path = $path ?? sys_get_temp_dir(); @@ -30,7 +34,9 @@ public function __construct($prefix = 'cache', $path = null, $logger = null) * @param string $key The object KEY * @param mixed $default IGNORED IN MEMCACHED. * @return mixed Description - * @throws \Psr\SimpleCache\InvalidArgumentException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws \ByJG\Cache\Exception\InvalidArgumentException */ public function get(string $key, mixed $default = null): mixed { @@ -104,7 +110,7 @@ public function set(string $key, mixed $value, DateInterval|int|null $ttl = null $validUntil = $this->addToNow($ttl); if (!empty($validUntil)) { - file_put_contents($fileKey . ".ttl", $validUntil); + file_put_contents($fileKey . ".ttl", (string)$validUntil); } } catch (Exception $ex) { $this->logger->warning("[Filesystem cache] I could not write to cache on file '" . basename($key) . "'. Switching to nocache=true mode."); @@ -117,7 +123,6 @@ public function set(string $key, mixed $value, DateInterval|int|null $ttl = null /** * @param string $key * @return bool - * @throws \Psr\SimpleCache\InvalidArgumentException */ public function delete(string $key): bool { @@ -146,7 +151,7 @@ public function lock(string $key): void * UnLock resource after set it. * @param string $key */ - public function unlock($key): void + public function unlock(string $key): void { $this->logger->info("[Filesystem cache] Unlock '$key'"); @@ -158,12 +163,22 @@ public function unlock($key): void } } + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws \ByJG\Cache\Exception\InvalidArgumentException + */ public function isAvailable(): bool { return is_writable(dirname($this->fixKey('test'))); } - protected function fixKey($key) + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws \ByJG\Cache\Exception\InvalidArgumentException + */ + protected function fixKey(string $key): string { $key = $this->getKeyFromContainer($key); @@ -177,6 +192,9 @@ protected function fixKey($key) * Wipes clean the entire cache's keys. * * @return bool True on success and false on failure. + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws \ByJG\Cache\Exception\InvalidArgumentException */ public function clear(): bool { @@ -197,8 +215,9 @@ public function clear(): bool * * @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. + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws \ByJG\Cache\Exception\InvalidArgumentException */ public function has(string $key): bool { diff --git a/src/Psr16/MemcachedEngine.php b/src/Psr16/MemcachedEngine.php index e382b6b..299092a 100644 --- a/src/Psr16/MemcachedEngine.php +++ b/src/Psr16/MemcachedEngine.php @@ -2,9 +2,13 @@ namespace ByJG\Cache\Psr16; +use ByJG\Cache\Exception\InvalidArgumentException; use ByJG\Cache\Exception\StorageErrorException; use DateInterval; use Memcached; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; +use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; class MemcachedEngine extends BaseCacheEngine @@ -12,15 +16,15 @@ class MemcachedEngine extends BaseCacheEngine /** * - * @var Memcached + * @var Memcached|null */ - protected $memCached = null; + protected Memcached|null $memCached = null; - protected $logger = null; + protected LoggerInterface|null $logger = null; - protected $servers = null; + protected ?array $servers = null; - public function __construct($servers = null, $logger = null) + public function __construct(?array $servers = null, $logger = null) { $this->servers = (array)$servers; if (is_null($servers)) { @@ -35,7 +39,13 @@ public function __construct($servers = null, $logger = null) } } - protected function fixKey($key) { + /** + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface + */ + protected function fixKey(string $key): string + { $key = $this->getKeyFromContainer($key); return "cache-" . $key; } @@ -43,13 +53,13 @@ protected function fixKey($key) { /** * @throws StorageErrorException */ - protected function lazyLoadMemCachedServers() + protected function lazyLoadMemCachedServers(): void { if (is_null($this->memCached)) { $this->memCached = new Memcached(); foreach ($this->servers as $server) { $data = explode(":", $server); - $this->memCached->addServer($data[0], $data[1]); + $this->memCached->addServer($data[0], intval($data[1])); $stats = $this->memCached->getStats(); if (!isset($stats[$server]) || $stats[$server]['pid'] === -1) { @@ -60,9 +70,12 @@ protected function lazyLoadMemCachedServers() } /** - * @param string $key The object KEY - * @param int $default IGNORED IN MEMCACHED. - * @return mixed Description + * @param string $key + * @param mixed|null $default + * @return mixed + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface * @throws StorageErrorException */ public function get(string $key, mixed $default = null): mixed @@ -83,6 +96,9 @@ public function get(string $key, mixed $default = null): mixed * @param mixed $value The object to be cached * @param DateInterval|int|null $ttl The time to live in seconds of this objects * @return bool If the object is successfully posted + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface * @throws StorageErrorException */ public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool @@ -103,6 +119,9 @@ public function set(string $key, mixed $value, DateInterval|int|null $ttl = null /** * @param string $key * @return bool + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface * @throws StorageErrorException */ public function delete(string $key): bool @@ -141,6 +160,9 @@ public function clear(): bool /** * @param string $key * @return bool + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface * @throws StorageErrorException */ public function has(string $key): bool diff --git a/src/Psr16/NoCacheEngine.php b/src/Psr16/NoCacheEngine.php index f453a62..c384277 100644 --- a/src/Psr16/NoCacheEngine.php +++ b/src/Psr16/NoCacheEngine.php @@ -3,14 +3,20 @@ namespace ByJG\Cache\Psr16; use ByJG\Cache\CacheLockInterface; +use ByJG\Cache\Exception\InvalidArgumentException; use DateInterval; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; class NoCacheEngine extends BaseCacheEngine implements CacheLockInterface { /** - * @param string $key The object KEY - * @param int $default IGNORED IN MEMCACHED. - * @return mixed Description + * @param string $key + * @param mixed $default + * @return mixed + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface */ public function get(string $key, mixed $default = null): mixed { @@ -19,10 +25,13 @@ public function get(string $key, mixed $default = null): mixed } /** - * @param string $key The object Key - * @param object $value The object to be cached - * @param int $ttl The time to live in seconds of this objects - * @return bool If the object is successfully posted + * @param string $key + * @param mixed $value + * @param DateInterval|int|null $ttl + * @return bool + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface */ public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool { @@ -33,6 +42,9 @@ public function set(string $key, mixed $value, DateInterval|int|null $ttl = null /** * @param string $key * @return bool + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface */ public function delete(string $key): bool { @@ -82,9 +94,10 @@ public function clear(): bool * * @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. - */ + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface + */ public function has(string $key): bool { $key = $this->getKeyFromContainer($key); diff --git a/src/Psr16/RedisCacheEngine.php b/src/Psr16/RedisCacheEngine.php index 2b1089d..703b2b9 100644 --- a/src/Psr16/RedisCacheEngine.php +++ b/src/Psr16/RedisCacheEngine.php @@ -2,25 +2,31 @@ namespace ByJG\Cache\Psr16; +use ByJG\Cache\Exception\InvalidArgumentException; use DateInterval; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; +use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; +use Redis; +use RedisException; class RedisCacheEngine extends BaseCacheEngine { /** * - * @var \Redis + * @var Redis */ - protected $redis = null; + protected ?Redis $redis = null; - protected $logger = null; + protected LoggerInterface|null $logger = null; - protected $server = null; + protected ?string $server = null; - protected $password = null; + protected ?string $password = null; - public function __construct($server = null, $password = null, $logger = null) + public function __construct(?string $server = null, ?string $password = null, ?LoggerInterface $logger = null) { $this->server = $server; if (is_null($server)) { @@ -35,31 +41,44 @@ public function __construct($server = null, $password = null, $logger = null) } } - protected function lazyLoadRedisServer() + /** + * @throws RedisException + */ + protected function lazyLoadRedisServer(): void { if (is_null($this->redis)) { - $this->redis = new \Redis(); + $this->redis = new Redis(); $data = explode(":", $this->server); - $this->redis->connect($data[0], isset($data[1]) ? $data[1] : 6379); + $this->redis->connect($data[0], intval($data[1] ?? 6379)); if (!empty($this->password)) { $this->redis->auth($this->password); } - $this->redis->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_NONE); + $this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE); $this->redis->info('redis_version'); } } - protected function fixKey($key) { + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws InvalidArgumentException + */ + protected function fixKey(string $key): string + { $key = $this->getKeyFromContainer($key); return "cache:$key"; } /** - * @param string $key The object KEY - * @param int $default IGNORED IN MEMCACHED. - * @return mixed Description + * @param string $key + * @param mixed $default + * @return mixed + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface + * @throws RedisException */ public function get(string $key, mixed $default = null): mixed { @@ -72,10 +91,14 @@ public function get(string $key, mixed $default = null): mixed } /** - * @param string $key The object Key - * @param object $value The object to be cached - * @param int $ttl The time to live in seconds of this objects - * @return bool If the object is successfully posted + * @param string $key + * @param mixed $value + * @param DateInterval|int|null $ttl + * @return bool + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface + * @throws RedisException */ public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool { @@ -89,6 +112,12 @@ public function set(string $key, mixed $value, DateInterval|int|null $ttl = null return true; } + /** + * @throws NotFoundExceptionInterface + * @throws InvalidArgumentException + * @throws RedisException + * @throws ContainerExceptionInterface + */ public function delete(string $key): bool { $this->lazyLoadRedisServer(); @@ -98,6 +127,12 @@ public function delete(string $key): bool return true; } + /** + * @throws NotFoundExceptionInterface + * @throws InvalidArgumentException + * @throws RedisException + * @throws ContainerExceptionInterface + */ public function clear(): bool { $keys = $this->redis->keys('cache:*'); @@ -109,6 +144,12 @@ public function clear(): bool return true; } + /** + * @throws NotFoundExceptionInterface + * @throws InvalidArgumentException + * @throws RedisException + * @throws ContainerExceptionInterface + */ public function has(string $key): bool { $result = $this->redis->exists($this->fixKey($key)); @@ -117,6 +158,10 @@ public function has(string $key): bool return $result !== 0; } + if ($result instanceof Redis) { + return true; + } + return $result; } diff --git a/src/Psr16/SessionCacheEngine.php b/src/Psr16/SessionCacheEngine.php index cde9588..6b69cc1 100644 --- a/src/Psr16/SessionCacheEngine.php +++ b/src/Psr16/SessionCacheEngine.php @@ -2,37 +2,51 @@ namespace ByJG\Cache\Psr16; +use ByJG\Cache\Exception\InvalidArgumentException; use DateInterval; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; class SessionCacheEngine extends BaseCacheEngine { - protected $prefix = null; + protected string $prefix; /** * SessionCacheEngine constructor. * * @param string $prefix */ - public function __construct($prefix = 'cache') + public function __construct(string $prefix = 'cache') { $this->prefix = $prefix; } - protected function checkSession() + protected function checkSession(): void { if (session_status() == PHP_SESSION_NONE) { session_start(); } } - protected function keyName($key) + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws InvalidArgumentException + */ + protected function keyName($key): string { $key = $this->getKeyFromContainer($key); return $this->prefix . '-' . $key; } + /** + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface + * @throws ContainerExceptionInterface + * @throws \Psr\SimpleCache\InvalidArgumentException + */ public function get(string $key, mixed $default = null): mixed { $this->checkSession(); @@ -46,6 +60,11 @@ public function get(string $key, mixed $default = null): mixed } } + /** + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface + */ public function delete(string $key): bool { $this->checkSession(); diff --git a/src/Psr16/ShmopCacheEngine.php b/src/Psr16/ShmopCacheEngine.php index 91f5844..d2ea023 100644 --- a/src/Psr16/ShmopCacheEngine.php +++ b/src/Psr16/ShmopCacheEngine.php @@ -5,6 +5,9 @@ use ByJG\Cache\Exception\InvalidArgumentException; use ByJG\Cache\Exception\StorageErrorException; use DateInterval; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; +use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; /** @@ -24,11 +27,11 @@ */ class ShmopCacheEngine extends BaseCacheEngine { - protected $logger = null; + protected LoggerInterface|null $logger = null; - protected $config = []; + protected array $config = []; - public function __construct($config = [], $logger = null) + public function __construct(array $config = [], ?LoggerInterface $logger = null) { $this->config = $config; @@ -45,7 +48,12 @@ public function __construct($config = [], $logger = null) } } - protected function getFilenameToken($key) + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws InvalidArgumentException + */ + protected function getFilenameToken(string $key): string { $key = $this->getKeyFromContainer($key); return sys_get_temp_dir() . '/shmop-' . sha1($key) . '.cache'; @@ -61,7 +69,7 @@ protected function getDefaultPermission() return $this->config['default-permission']; } - protected function getFTok($file) + protected function getFTok(string $file): int { if (!file_exists($file)) { touch($file); @@ -73,6 +81,9 @@ protected function getFTok($file) * @param string $key The object KEY * @param mixed $default The time to live in seconds of the object. Depends on implementation. * @return mixed The Object + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface */ public function get(string $key, mixed $default = null): mixed { @@ -103,7 +114,7 @@ public function get(string $key, mixed $default = null): mixed return unserialize($serialized); } - protected function isValidAge($file) + protected function isValidAge(string $file): bool { if (file_exists("$file.ttl")) { $fileTtl = intval(file_get_contents("$file.ttl")); @@ -127,7 +138,9 @@ protected function isValidAge($file) * 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 ContainerExceptionInterface * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface * @throws StorageErrorException */ public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool @@ -164,7 +177,7 @@ public function set(string $key, mixed $value, DateInterval|int|null $ttl = null $validUntil = $this->addToNow($ttl); if (!empty($validUntil)) { - file_put_contents("$file.ttl", $validUntil); + file_put_contents("$file.ttl", (string)$validUntil); } return true; @@ -173,6 +186,9 @@ public function set(string $key, mixed $value, DateInterval|int|null $ttl = null /** * @param string $key * @return bool + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface */ public function delete(string $key): bool { @@ -188,7 +204,7 @@ public function delete(string $key): bool return true; } - private function deleteFromFilenameToken($file) + private function deleteFromFilenameToken(string $file): void { $filekey = $this->getFTok($file); $shm_id = @shmop_open($filekey, "w", 0, 0); @@ -219,6 +235,11 @@ public function clear(): bool return true; } + /** + * @throws ContainerExceptionInterface + * @throws InvalidArgumentException + * @throws NotFoundExceptionInterface + */ public function has(string $key): bool { $file = $this->getFilenameToken($key); @@ -234,7 +255,7 @@ public function has(string $key): bool return $this->isValidAge($file); } - return $exists; + return false; } diff --git a/src/Psr6/CachePool.php b/src/Psr6/CachePool.php index bf37e35..e3141ce 100644 --- a/src/Psr6/CachePool.php +++ b/src/Psr6/CachePool.php @@ -11,9 +11,9 @@ class CachePool implements CacheItemPoolInterface { /** - * @var CacheInterface + * @var BaseCacheEngine */ - protected CacheInterface $_cacheEngine; + protected BaseCacheEngine $_cacheEngine; /** * @var CacheItem diff --git a/tests/BaseCacheTest.php b/tests/BaseCacheTest.php index a0099be..ac24d6e 100644 --- a/tests/BaseCacheTest.php +++ b/tests/BaseCacheTest.php @@ -1,11 +1,9 @@ isAvailable()) { // First time - $items = $cacheEngine->getMultiple(['chave1', 'chave2']); + $items = [...$cacheEngine->getMultiple(['chave1', 'chave2'])]; $this->assertNull($items['chave1']); $this->assertNull($items['chave2']); - $items = $cacheEngine->getMultiple(['chave1', 'chave2'], 'default'); + $items = [...$cacheEngine->getMultiple(['chave1', 'chave2'], 'default')]; $this->assertEquals('default', $items['chave1']); $this->assertEquals('default', $items['chave2']); @@ -73,7 +68,7 @@ public function testGetMultipleItems(BaseCacheEngine $cacheEngine) // Get Object if (!($cacheEngine instanceof NoCacheEngine)) { - $item2 = $cacheEngine->getMultiple(['chave1', 'chave2']); + $item2 = [...$cacheEngine->getMultiple(['chave1', 'chave2'])]; $this->assertEquals('valor1', $item2['chave1']); $this->assertEquals('valor2', $item2['chave2']); } @@ -82,7 +77,7 @@ public function testGetMultipleItems(BaseCacheEngine $cacheEngine) $cacheEngine->deleteMultiple(['chave1', 'chave2']); // Check Removed - $items = $cacheEngine->getMultiple(['chave1', 'chave2']); + $items = [...$cacheEngine->getMultiple(['chave1', 'chave2'])]; $this->assertNull($items['chave1']); $this->assertNull($items['chave2']); } else { @@ -92,7 +87,7 @@ public function testGetMultipleItems(BaseCacheEngine $cacheEngine) /** * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine + * @param BaseCacheEngine $cacheEngine * @throws \Psr\SimpleCache\InvalidArgumentException */ public function testTtl(BaseCacheEngine $cacheEngine) @@ -129,7 +124,7 @@ public function testTtl(BaseCacheEngine $cacheEngine) /** * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine + * @param BaseCacheEngine $cacheEngine * @throws \Psr\SimpleCache\InvalidArgumentException */ public function testCacheObject(BaseCacheEngine $cacheEngine) @@ -162,8 +157,7 @@ public function testCacheObject(BaseCacheEngine $cacheEngine) /** * @dataProvider CachePoolProvider - * @param \ByJG\Cache\Psr16\BaseCacheEngine $cacheEngine - * @throws \ByJG\Cache\InvalidArgumentException + * @param BaseCacheEngine $cacheEngine * @throws \Psr\SimpleCache\InvalidArgumentException */ public function testClear(BaseCacheEngine $cacheEngine) diff --git a/tests/CachePSR6Test.php b/tests/CachePSR6Test.php index 36bb268..649be98 100644 --- a/tests/CachePSR6Test.php +++ b/tests/CachePSR6Test.php @@ -1,13 +1,11 @@ Date: Sun, 15 Sep 2024 15:46:40 -0500 Subject: [PATCH 5/7] Add Types --- src/Factory.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Factory.php b/src/Factory.php index 4b9f74f..9e58f19 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -10,6 +10,7 @@ use ByJG\Cache\Psr16\SessionCacheEngine; use ByJG\Cache\Psr16\ShmopCacheEngine; use ByJG\Cache\Psr6\CachePool; +use Psr\Log\LoggerInterface; class Factory { @@ -20,7 +21,7 @@ public static function createNullPool(): CachePool ); } - public static function createSessionPool($prefix = null, $bufferSize = null): CachePool + public static function createSessionPool(string $prefix = 'cache', int $bufferSize = 10): CachePool { return new CachePool( new SessionCacheEngine($prefix), @@ -28,7 +29,7 @@ public static function createSessionPool($prefix = null, $bufferSize = null): Ca ); } - public static function createFilePool($prefix = null, $path = null, $bufferSize = null, $logger = null): CachePool + public static function createFilePool(string $prefix = 'cache', ?string $path = null, int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool { return new CachePool( new FileSystemCacheEngine($prefix, $path, $logger), @@ -36,7 +37,7 @@ public static function createFilePool($prefix = null, $path = null, $bufferSize ); } - public static function createShmopPool($config = [], $bufferSize = null, $logger = null): CachePool + public static function createShmopPool(array $config = [], int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool { return new CachePool( new ShmopCacheEngine($config, $logger), @@ -44,7 +45,7 @@ public static function createShmopPool($config = [], $bufferSize = null, $logger ); } - public static function createArrayPool($bufferSize = null, $logger = null): CachePool + public static function createArrayPool(int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool { return new CachePool( new ArrayCacheEngine($logger), @@ -52,7 +53,7 @@ public static function createArrayPool($bufferSize = null, $logger = null): Cach ); } - public static function createMemcachedPool($servers = null, $bufferSize = null, $logger = null): CachePool + public static function createMemcachedPool(?array $servers = null, int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool { return new CachePool( new MemcachedEngine($servers, $logger), @@ -60,7 +61,7 @@ public static function createMemcachedPool($servers = null, $bufferSize = null, ); } - public static function createRedisCacheEngine($servers = null, $password = null, $bufferSize = null, $logger = null): CachePool + public static function createRedisCacheEngine(?string $servers = null, ?string $password = null, int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool { return new CachePool( new RedisCacheEngine($servers, $password, $logger), From b577a6368939daeecdb095931e09643eac95f0c0 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Thu, 3 Oct 2024 08:21:09 -0500 Subject: [PATCH 6/7] =?UTF-8?q?Allow=20to=20create=20path=20on=20FileSyste?= =?UTF-8?q?mCacheEngine=20if=20doesn=C2=B4t=20exist.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Factory.php | 4 ++-- src/Psr16/FileSystemCacheEngine.php | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Factory.php b/src/Factory.php index 9e58f19..6e1858d 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -29,10 +29,10 @@ public static function createSessionPool(string $prefix = 'cache', int $bufferSi ); } - public static function createFilePool(string $prefix = 'cache', ?string $path = null, int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool + public static function createFilePool(string $prefix = 'cache', ?string $path = null, int $bufferSize = 10, ?LoggerInterface $logger = null, bool $createPath = false): CachePool { return new CachePool( - new FileSystemCacheEngine($prefix, $path, $logger), + new FileSystemCacheEngine($prefix, $path, $logger, $createPath), $bufferSize ); } diff --git a/src/Psr16/FileSystemCacheEngine.php b/src/Psr16/FileSystemCacheEngine.php index b5b2d0f..3580446 100644 --- a/src/Psr16/FileSystemCacheEngine.php +++ b/src/Psr16/FileSystemCacheEngine.php @@ -19,10 +19,13 @@ class FileSystemCacheEngine extends BaseCacheEngine implements CacheLockInterfac protected ?string $prefix = null; protected ?string $path = null; - public function __construct(string $prefix = 'cache', ?string $path = null, ?LoggerInterface $logger = null) + public function __construct(string $prefix = 'cache', ?string $path = null, ?LoggerInterface $logger = null, bool $createPath = false) { $this->prefix = $prefix; $this->path = $path ?? sys_get_temp_dir(); + if ($createPath && !file_exists($this->path)) { + mkdir($this->path, 0777, true); + } $this->logger = $logger; if (is_null($logger)) { From 36544b814ff7e9498550dfdb2cbf4cc72d9a4220 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sun, 27 Oct 2024 10:18:52 -0500 Subject: [PATCH 7/7] Limit PHP Version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0f6630b..0053294 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ } }, "require": { - "php": ">=8.1", + "php": ">=8.1 <8.4", "psr/cache": "^1.0|^2.0|^3.0", "psr/log": "^1.0|^1.1|^2.0", "psr/simple-cache": "^1.0|^2.0",