diff --git a/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php index 97be852ac534a..7b92387742894 100644 --- a/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Cache\Adapter; use Psr\Cache\CacheItemInterface; +use Psr\Clock\ClockInterface; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; use Symfony\Component\Cache\CacheItem; @@ -44,6 +45,7 @@ public function __construct( private bool $storeSerialized = true, private float $maxLifetime = 0, private int $maxItems = 0, + private ?ClockInterface $clock = null, ) { if (0 > $maxLifetime) { throw new InvalidArgumentException(\sprintf('Argument $maxLifetime must be positive, %F passed.', $maxLifetime)); @@ -94,7 +96,7 @@ public function delete(string $key): bool public function hasItem(mixed $key): bool { - if (\is_string($key) && isset($this->expiries[$key]) && $this->expiries[$key] > microtime(true)) { + if (\is_string($key) && isset($this->expiries[$key]) && $this->expiries[$key] > $this->getCurrentTime()) { if ($this->maxItems) { // Move the item last in the storage $value = $this->values[$key]; @@ -129,7 +131,7 @@ public function getItems(array $keys = []): iterable { \assert(self::validateKeys($keys)); - return $this->generateItems($keys, microtime(true), self::$createCacheItem); + return $this->generateItems($keys, $this->getCurrentTime(), self::$createCacheItem); } public function deleteItem(mixed $key): bool @@ -159,7 +161,7 @@ public function save(CacheItemInterface $item): bool $value = $item["\0*\0value"]; $expiry = $item["\0*\0expiry"]; - $now = microtime(true); + $now = $this->getCurrentTime(); if (null !== $expiry) { if (!$expiry) { @@ -216,7 +218,7 @@ public function commit(): bool public function clear(string $prefix = ''): bool { if ('' !== $prefix) { - $now = microtime(true); + $now = $this->getCurrentTime(); foreach ($this->values as $key => $value) { if (!isset($this->expiries[$key]) || $this->expiries[$key] <= $now || str_starts_with($key, $prefix)) { @@ -356,4 +358,9 @@ private function validateKeys(array $keys): bool return true; } + + private function getCurrentTime(): float + { + return $this->clock?->now()->format('U.u') ?? microtime(true); + } } diff --git a/src/Symfony/Component/Cache/CHANGELOG.md b/src/Symfony/Component/Cache/CHANGELOG.md index cab9bf61c88cb..c473b468b0d89 100644 --- a/src/Symfony/Component/Cache/CHANGELOG.md +++ b/src/Symfony/Component/Cache/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.2 +--- + + * Add optional `Psr\Clock\ClockInterface` parameter to `ArrayAdapter` + 7.1 --- diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ArrayAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ArrayAdapterTest.php index c49cc3198b32e..7a2234454aa9e 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/ArrayAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/ArrayAdapterTest.php @@ -14,6 +14,7 @@ use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Cache\Adapter\ArrayAdapter; use Symfony\Component\Cache\Tests\Fixtures\TestEnum; +use Symfony\Component\Clock\MockClock; /** * @group time-sensitive @@ -102,4 +103,17 @@ public function testEnum() $this->assertSame(TestEnum::Foo, $cache->getItem('foo')->get()); } + + public function testClockAware() + { + $clock = new MockClock(); + $cache = new ArrayAdapter(10, false, 0, 0, $clock); + + $cache->save($cache->getItem('foo')); + $this->assertTrue($cache->hasItem('foo')); + + $clock->modify('+11 seconds'); + + $this->assertFalse($cache->hasItem('foo')); + } } diff --git a/src/Symfony/Component/Cache/composer.json b/src/Symfony/Component/Cache/composer.json index d537037ae6d09..bdb461be8c9e2 100644 --- a/src/Symfony/Component/Cache/composer.json +++ b/src/Symfony/Component/Cache/composer.json @@ -34,6 +34,7 @@ "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0", "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/clock": "^6.4|^7.0", "symfony/config": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", "symfony/filesystem": "^6.4|^7.0",