poolName = preg_replace("/[^a-zA-Z0-9_\\-]/", "_", $poolName); $this->cacheDir = $this->findCachePath(); } protected function findCachePath(): string { $candidates = [ '/var/cache', getenv("HOME").'/.cache', ]; while ($candidate = array_shift($candidates)) { if (!is_writable($candidate)) { continue; } $path = $candidate . DIRECTORY_SEPARATOR . 'php-localcache'; /* if (!is_dir($path)) { @mkdir($path); if (!is_dir($path)) { continue; } } */ return $path; } throw new CacheException("Couldn't find a usable cache directory"); } protected function hashKey(string $key) { $hash = hash("sha256", $key); return $hash; } protected function getKeyPath(string $key) { $hash = $this->hashKey($key); $path = substr($hash, 0, 2) . DIRECTORY_SEPARATOR . substr($hash, 2, 2) . DIRECTORY_SEPARATOR . $hash; $full = $this->cacheDir . DIRECTORY_SEPARATOR . $this->poolName . DIRECTORY_SEPARATOR . $path; return $full; } /** * {@inheritDoc} */ public function get($key, $default = null) { if (!$this->has($key)) { return $default; } $path = $this->getKeyPath($key); return file_get_contents($path); } /** * {@inheritDoc} */ public function set($key, $value, $ttl = null) { $info = [ 'key' => $key, 'ttl' => $ttl ?? $this->defaultTtl ]; $info['expires'] = time() + $info['ttl']; $path = $this->getKeyPath($key); if (!is_dir(dirname($path))) { mkdir(dirname($path), 0777, true); } file_put_contents($path, $value); file_put_contents($path.".info", serialize($info)); } /** * {@inheritDoc} */ public function delete($key) { if (!$this->has($key)) { return; } $path = $this->getKeyPath($key); @unlink($path); @unlink($path.".info"); } /** * {@inheritDoc} */ public function has($key) { $path = $this->getKeyPath($key); if (!file_exists($path)) { return false; } $info = unserialize(file_get_contents($path.".info")); if ($info['expires'] < time()) { return false; } return true; } /** * {@inheritDoc} */ public function clear() { /* $items = glob($this->cacheDir.DIRECTORY_SEPARATOR.$this->poolName.DIRECTORY_SEPARATOR."*.info"); foreach ($items as $item) { unlink(substr($item, 0, -5)); unlink($item); } @rmdir($this->cacheDir . DIRECTORY_SEPARATOR . $this->poolName); */ $path = $this->cacheDir . DIRECTORY_SEPARATOR . $this->poolName; exec("rm -rf ".escapeshellarg($path)); } /** * {@inheritDoc} */ public function getMultiple($keys, $default = null) { if (!is_iterable($keys)) { throw new InvalidArgumentException("Argument not iterable"); } $ret = []; foreach ($keys as $key) { $ret[$key] = $this->get($key, $default); } return $ret; } /** * {@inheritDoc} */ public function setMultiple($values, $ttl = null) { if (!is_iterable($values)) { throw new InvalidArgumentException("Argument not iterable"); } foreach ($values as $key=>$value) { $this->set($key, $value, $ttl); } } /** * {@inheritDoc} */ public function deleteMultiple($keys) { if (!is_iterable($keys)) { throw new InvalidArgumentException("Argument not iterable"); } foreach ($keys as $key) { $this->delete($key); } } }