Merge commit '1392bd3a96045302b60d845a90901a4b2234c475' as 'seatmap-webapi'
This commit is contained in:
149
seatmap-webapi/src/Tqdev/PhpCrudApi/Cache/TempFileCache.php
Normal file
149
seatmap-webapi/src/Tqdev/PhpCrudApi/Cache/TempFileCache.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
namespace Tqdev\PhpCrudApi\Cache;
|
||||
|
||||
class TempFileCache implements Cache
|
||||
{
|
||||
const SUFFIX = 'cache';
|
||||
|
||||
private $path;
|
||||
private $segments;
|
||||
|
||||
public function __construct(string $prefix, string $config)
|
||||
{
|
||||
$this->segments = [];
|
||||
$s = DIRECTORY_SEPARATOR;
|
||||
$ps = PATH_SEPARATOR;
|
||||
if ($config == '') {
|
||||
$this->path = sys_get_temp_dir() . $s . $prefix . self::SUFFIX;
|
||||
} elseif (strpos($config, $ps) === false) {
|
||||
$this->path = $config;
|
||||
} else {
|
||||
list($path, $segments) = explode($ps, $config);
|
||||
$this->path = $path;
|
||||
$this->segments = explode(',', $segments);
|
||||
}
|
||||
if (file_exists($this->path) && is_dir($this->path)) {
|
||||
$this->clean($this->path, array_filter($this->segments), strlen(md5('')), false);
|
||||
}
|
||||
}
|
||||
|
||||
private function getFileName(string $key): string
|
||||
{
|
||||
$s = DIRECTORY_SEPARATOR;
|
||||
$md5 = md5($key);
|
||||
$filename = rtrim($this->path, $s) . $s;
|
||||
$i = 0;
|
||||
foreach ($this->segments as $segment) {
|
||||
$filename .= substr($md5, $i, $segment) . $s;
|
||||
$i += $segment;
|
||||
}
|
||||
$filename .= substr($md5, $i);
|
||||
return $filename;
|
||||
}
|
||||
|
||||
public function set(string $key, string $value, int $ttl = 0): bool
|
||||
{
|
||||
$filename = $this->getFileName($key);
|
||||
$dirname = dirname($filename);
|
||||
if (!file_exists($dirname)) {
|
||||
if (!mkdir($dirname, 0755, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$string = $ttl . '|' . $value;
|
||||
return $this->filePutContents($filename, $string) !== false;
|
||||
}
|
||||
|
||||
private function filePutContents($filename, $string)
|
||||
{
|
||||
return file_put_contents($filename, $string, LOCK_EX);
|
||||
}
|
||||
|
||||
private function fileGetContents($filename)
|
||||
{
|
||||
$file = fopen($filename, 'rb');
|
||||
if ($file === false) {
|
||||
return false;
|
||||
}
|
||||
$lock = flock($file, LOCK_SH);
|
||||
if (!$lock) {
|
||||
fclose($file);
|
||||
return false;
|
||||
}
|
||||
$string = '';
|
||||
while (!feof($file)) {
|
||||
$string .= fread($file, 8192);
|
||||
}
|
||||
flock($file, LOCK_UN);
|
||||
fclose($file);
|
||||
return $string;
|
||||
}
|
||||
|
||||
private function getString($filename): string
|
||||
{
|
||||
$data = $this->fileGetContents($filename);
|
||||
if ($data === false) {
|
||||
return '';
|
||||
}
|
||||
if (strpos($data, '|') === false) {
|
||||
return '';
|
||||
}
|
||||
list($ttl, $string) = explode('|', $data, 2);
|
||||
if ($ttl > 0 && time() - filemtime($filename) > $ttl) {
|
||||
return '';
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
public function get(string $key): string
|
||||
{
|
||||
$filename = $this->getFileName($key);
|
||||
if (!file_exists($filename)) {
|
||||
return '';
|
||||
}
|
||||
$string = $this->getString($filename);
|
||||
if ($string == null) {
|
||||
return '';
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
private function clean(string $path, array $segments, int $len, bool $all) /*: void*/
|
||||
{
|
||||
$entries = scandir($path);
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry === '.' || $entry === '..') {
|
||||
continue;
|
||||
}
|
||||
$filename = $path . DIRECTORY_SEPARATOR . $entry;
|
||||
if (count($segments) == 0) {
|
||||
if (strlen($entry) != $len) {
|
||||
continue;
|
||||
}
|
||||
if (file_exists($filename) && is_file($filename)) {
|
||||
if ($all || $this->getString($filename) == null) {
|
||||
@unlink($filename);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (strlen($entry) != $segments[0]) {
|
||||
continue;
|
||||
}
|
||||
if (file_exists($filename) && is_dir($filename)) {
|
||||
$this->clean($filename, array_slice($segments, 1), $len - $segments[0], $all);
|
||||
@rmdir($filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function clear(): bool
|
||||
{
|
||||
if (!file_exists($this->path) || !is_dir($this->path)) {
|
||||
return false;
|
||||
}
|
||||
$this->clean($this->path, array_filter($this->segments), strlen(md5('')), true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user