diff --git a/CHANGELOG.md b/CHANGELOG.md index 80d0fa0..be0a71b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 3.1.1 under development -- no changes in this release. +- Bug #85: Clear stat cache in `FileCache::set()` (@samdark) ## 3.1.0 October 09, 2023 diff --git a/src/FileCache.php b/src/FileCache.php index 3afb893..77d5fc2 100644 --- a/src/FileCache.php +++ b/src/FileCache.php @@ -132,7 +132,7 @@ public function set(string $key, mixed $value, null|int|DateInterval $ttl = null throw new CacheException("Failed to create cache directory \"$cacheDirectory\"."); } - // If ownership differs the touch call will fail, so we try to + // If ownership differs, the touch call will fail, so we try to // rebuild the file from scratch by deleting it first // https://github.com/yiisoft/yii2/pull/16120 if (function_exists('posix_geteuid') && is_file($file) && fileowner($file) !== posix_geteuid()) { @@ -150,7 +150,12 @@ public function set(string $key, mixed $value, null|int|DateInterval $ttl = null } } - $result = @touch($file, $expiration); + $result = false; + + if (@touch($file, $expiration)) { + clearstatcache(); + $result = true; + } return $this->isLastErrorSafe($result); } diff --git a/tests/FileCacheTest.php b/tests/FileCacheTest.php index abb8e54..9077fdc 100644 --- a/tests/FileCacheTest.php +++ b/tests/FileCacheTest.php @@ -647,4 +647,22 @@ private function removeDirectory(string $directory): void rmdir($directory); } + + public function testSetClearsStatCache(): void + { + $this->cache->set(__FUNCTION__, 'cache1', 2); + + $refClass = new \ReflectionClass($this->cache); + $refMethodGetCacheFile = $refClass->getMethod('getCacheFile'); + $refMethodGetCacheFile->setAccessible(true); + $cacheFile = $refMethodGetCacheFile->invoke($this->cache, __FUNCTION__); + + // simulate cache expire 10 seconds ago + touch($cacheFile, time() - 10); + clearstatcache(); + + $this->assertNull($this->cache->get(__FUNCTION__)); + $this->assertTrue($this->cache->set(__FUNCTION__, 'cache2', 2)); + $this->assertSame('cache2', $this->cache->get(__FUNCTION__)); + } }