hehexu

博客园 首页 新随笔 联系 订阅 管理
<?php
class FileCache
{

public $keyPrefix = '';

public $cachePath = '';

public $cacheFileSuffix = '.bin';

public $directoryLevel = 1;

public $gcProbability = 10;

public $fileMode;

public $dirMode = 0775;


function __construct()
{
$this->cachePath = HT::$cacheRoot.'htcache';
}

function FileCache()
{
$this->__construct();
}


public function set($key, $value, $duration = 0)
{
$value = serialize([$value]);
$key = $this->buildKey($key);
return $this->setValue($key, $value, $duration);
}


public function get($key)
{
$key = $this->buildKey($key);
$value = $this->getValue($key);
if ($value === false) {
return $value;
} else {
$value = unserialize($value);
}
if (is_array($value)) {
return $value[0];
} else {
return false;
}
}


public function delete($key)
{
$key = $this->buildKey($key);

return $this->deleteValue($key);
}


public function buildKey($key)
{
if (is_string($key)) {
$key = ctype_alnum($key) && mb_strlen($key, '8bit') <= 32 ? $key : md5($key);
} else {
$key = md5(json_encode($key, JSON_NUMERIC_CHECK));
}

return $this->keyPrefix . $key;
}


protected function setValue($key, $value, $duration)
{
$this->gc();
$cacheFile = $this->getCacheFile($key);
if ($this->directoryLevel > 0) {
@mkdir(dirname($cacheFile), $this->dirMode, true);
}
if (@file_put_contents($cacheFile, $value, LOCK_EX) !== false) {
if ($this->fileMode !== null) {
@chmod($cacheFile, $this->fileMode);
}
if ($duration <= 0) {
$duration = 31536000; // 1 year
}

return @touch($cacheFile, $duration + time());
} else {
$error = error_get_last();
HT::warning("Unable to write cache file '{$cacheFile}': {$error['message']}", __METHOD__);
return false;
}
}


protected function getValue($key)
{
$cacheFile = $this->getCacheFile($key);

if (@filemtime($cacheFile) > time()) {
$fp = @fopen($cacheFile, 'r');
if ($fp !== false) {
@flock($fp, LOCK_SH);
$cacheValue = @stream_get_contents($fp);
@flock($fp, LOCK_UN);
@fclose($fp);
return $cacheValue;
}
}

return false;
}


protected function deleteValue($key)
{
$cacheFile = $this->getCacheFile($key);

return @unlink($cacheFile);
}


protected function getCacheFile($key)
{
if ($this->directoryLevel > 0) {
$base = $this->cachePath;
for ($i = 0; $i < $this->directoryLevel; ++$i) {
if (($prefix = substr($key, $i + $i, 2)) !== false) {
$base .= DIRECTORY_SEPARATOR . $prefix;
}
}

return $base . DIRECTORY_SEPARATOR . $key . $this->cacheFileSuffix;
} else {
return $this->cachePath . DIRECTORY_SEPARATOR . $key . $this->cacheFileSuffix;
}
}


public function gc($force = false, $expiredOnly = true)
{
if ($force || mt_rand(0, 1000000) < $this->gcProbability) {
$this->gcRecursive($this->cachePath, $expiredOnly);
}
}


protected function gcRecursive($path, $expiredOnly)
{
if (($handle = opendir($path)) !== false) {
while (($file = readdir($handle)) !== false) {
if ($file[0] === '.') {
continue;
}
$fullPath = $path . DIRECTORY_SEPARATOR . $file;
if (is_dir($fullPath)) {
$this->gcRecursive($fullPath, $expiredOnly);
if (!$expiredOnly) {
if (!@rmdir($fullPath)) {
$error = error_get_last();
HT::warning("Unable to remove directory '{$fullPath}': {$error['message']}", __METHOD__);
}
}
} elseif (!$expiredOnly || $expiredOnly && @filemtime($fullPath) < time()) {
if (!@unlink($fullPath)) {
$error = error_get_last();
HT::warning("Unable to remove file '{$fullPath}': {$error['message']}", __METHOD__);
}
}
}
closedir($handle);
}
}
}
?>
posted on 2018-01-20 22:42  hehexu  阅读(51)  评论(0编辑  收藏  举报