*/ final class FileWatchingCache implements Cache { /** @var array> */ private array $timestamps = []; public function __construct( /** @var Cache */ private Cache $delegate, ) {} /** @internal */ public function get(string $key, mixed ...$arguments): mixed { $this->timestamps[$key] ??= $this->delegate->get("$key.timestamps"); // @phpstan-ignore assign.propertyType if ($this->timestamps[$key] === null) { return null; } assert(is_array($this->timestamps[$key])); foreach ($this->timestamps[$key] as $fileName => $timestamp) { if (! file_exists($fileName)) { return null; } if (filemtime($fileName) !== $timestamp) { return null; } } return $this->delegate->get($key, ...$arguments); } /** @internal */ public function set(string $key, CacheEntry $entry): void { $this->delegate->set($key, $entry); $this->timestamps[$key] = []; foreach ($entry->filesToWatch as $fileName) { $time = @filemtime($fileName); if (false === $time) { continue; } $this->timestamps[$key][$fileName] = $time; } $code = 'fn () => ' . var_export($this->timestamps[$key], true); $this->delegate->set("$key.timestamps", new CacheEntry($code)); } public function clear(): void { $this->timestamps = []; $this->delegate->clear(); } }