|
- <?php
- namespace VPSManager;
-
- final class BackupCache
- {
- private $directory;
- public function __construct(string $directory)
- {
- $real = realpath($directory);
- if (!$real || !is_dir($real) || is_link($directory) || (fileperms($real) & 0077) !== 0
- || !is_writable($real)) throw new \RuntimeException('CACHE_CONFIG');
- foreach ([dirname(__DIR__), $_SERVER['DOCUMENT_ROOT'] ?? ''] as $public) {
- $root = $public === '' ? false : realpath($public);
- if ($root && ($real === $root || strpos($real . '/', $root . '/') === 0)) throw new \RuntimeException('CACHE_PUBLIC');
- }
- // Administrator must choose a directory outside every web alias as well.
- $this->directory = $real;
- }
- public function read(string $key): ?array
- {
- $file = $this->directory . '/' . $key . '.json';
- if (!is_file($file) || is_link($file) || filesize($file) > 2097152) return null;
- $value = json_decode(file_get_contents($file), true, 32);
- return is_array($value) ? $value : null;
- }
- public function write(string $key, array $data): void
- {
- $file = tempnam($this->directory, '.new-');
- if ($file === false) throw new \RuntimeException('CACHE_WRITE');
- try {
- chmod($file, 0600);
- if (file_put_contents($file, json_encode($data, JSON_THROW_ON_ERROR), LOCK_EX) === false
- || !rename($file, $this->directory . '/' . $key . '.json')) throw new \RuntimeException('CACHE_WRITE');
- } finally { if (is_file($file)) unlink($file); }
- }
- }
|